Tests_User_Capabilities::test_user_add_cap()   B
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 38
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 20
nc 3
nop 0
dl 0
loc 38
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
// Test roles and capabilities via the WP_User class
4
5
/**
6
 * @group user
7
 * @group capabilities
8
 */
9
class Tests_User_Capabilities extends WP_UnitTestCase
10
{
11
12
    protected static $users = array(
13
    'administrator' => null,
14
    'editor'        => null,
15
    'author'        => null,
16
    'contributor'   => null,
17
    'subscriber'    => null,
18
    );
19
    protected static $super_admin = null;
20
21
    public static function wpSetUpBeforeClass( $factory ) 
0 ignored issues
show
Coding Style introduced by
The function name wpSetUpBeforeClass is in camel caps, but expected wp_set_up_before_class instead as per the coding standard.
Loading history...
22
    {
23
        self::$users = array(
24
         'administrator' => $factory->user->create_and_get(array( 'role' => 'administrator' )),
25
         'editor'        => $factory->user->create_and_get(array( 'role' => 'editor' )),
26
         'author'        => $factory->user->create_and_get(array( 'role' => 'author' )),
27
         'contributor'   => $factory->user->create_and_get(array( 'role' => 'contributor' )),
28
         'subscriber'    => $factory->user->create_and_get(array( 'role' => 'subscriber' )),
29
        );
30
        self::$super_admin = $factory->user->create_and_get(array( 'role' => 'contributor' ));
31
        grant_super_admin(self::$super_admin->ID);
32
    }
33
34
    function setUp() 
0 ignored issues
show
Coding Style introduced by
The function name setUp is in camel caps, but expected set_up instead as per the coding standard.
Loading history...
35
    {
36
        parent::setUp();
37
        // keep track of users we create
38
        $this->_flush_roles();
39
40
    }
41
42
    function _flush_roles() 
43
    {
44
        // we want to make sure we're testing against the db, not just in-memory data
45
        // this will flush everything and reload it from the db
46
        unset($GLOBALS['wp_user_roles']);
47
        global $wp_roles;
48
        $wp_roles = new WP_Roles();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
49
    }
50
51
    function _meta_yes_you_can( $can, $key, $post_id, $user_id, $cap, $caps ) 
52
    {
53
        return true;
54
    }
55
56
    function _meta_no_you_cant( $can, $key, $post_id, $user_id, $cap, $caps ) 
57
    {
58
        return false;
59
    }
60
61
    function _meta_filter( $meta_value, $meta_key, $meta_type ) 
62
    {
63
        return $meta_value;
64
    }
65
66
    final private function _getSingleSitePrimitiveCaps() 
0 ignored issues
show
Coding Style introduced by
The function name _getSingleSitePrimitiveCaps is in camel caps, but expected _get_single_site_primitive_caps instead as per the coding standard.
Loading history...
67
    {
68
        return array(
69
70
         'unfiltered_html'        => array( 'administrator', 'editor' ),
71
72
         'activate_plugins'       => array( 'administrator' ),
73
         'create_users'           => array( 'administrator' ),
74
         'delete_plugins'         => array( 'administrator' ),
75
         'delete_themes'          => array( 'administrator' ),
76
         'delete_users'           => array( 'administrator' ),
77
         'edit_files'             => array( 'administrator' ),
78
         'edit_plugins'           => array( 'administrator' ),
79
         'edit_themes'            => array( 'administrator' ),
80
         'edit_users'             => array( 'administrator' ),
81
         'install_plugins'        => array( 'administrator' ),
82
         'install_themes'         => array( 'administrator' ),
83
         'update_core'            => array( 'administrator' ),
84
         'update_plugins'         => array( 'administrator' ),
85
         'update_themes'          => array( 'administrator' ),
86
         'edit_theme_options'     => array( 'administrator' ),
87
         'export'                 => array( 'administrator' ),
88
         'import'                 => array( 'administrator' ),
89
         'list_users'             => array( 'administrator' ),
90
         'manage_options'         => array( 'administrator' ),
91
         'promote_users'          => array( 'administrator' ),
92
         'remove_users'           => array( 'administrator' ),
93
         'switch_themes'          => array( 'administrator' ),
94
         'edit_dashboard'         => array( 'administrator' ),
95
96
         'moderate_comments'      => array( 'administrator', 'editor' ),
97
         'manage_categories'      => array( 'administrator', 'editor' ),
98
         'edit_others_posts'      => array( 'administrator', 'editor' ),
99
         'edit_pages'             => array( 'administrator', 'editor' ),
100
         'edit_others_pages'      => array( 'administrator', 'editor' ),
101
         'edit_published_pages'   => array( 'administrator', 'editor' ),
102
         'publish_pages'          => array( 'administrator', 'editor' ),
103
         'delete_pages'           => array( 'administrator', 'editor' ),
104
         'delete_others_pages'    => array( 'administrator', 'editor' ),
105
         'delete_published_pages' => array( 'administrator', 'editor' ),
106
         'delete_others_posts'    => array( 'administrator', 'editor' ),
107
         'delete_private_posts'   => array( 'administrator', 'editor' ),
108
         'edit_private_posts'     => array( 'administrator', 'editor' ),
109
         'read_private_posts'     => array( 'administrator', 'editor' ),
110
         'delete_private_pages'   => array( 'administrator', 'editor' ),
111
         'edit_private_pages'     => array( 'administrator', 'editor' ),
112
         'read_private_pages'     => array( 'administrator', 'editor' ),
113
114
         'edit_published_posts'   => array( 'administrator', 'editor', 'author' ),
115
         'upload_files'           => array( 'administrator', 'editor', 'author' ),
116
         'publish_posts'          => array( 'administrator', 'editor', 'author' ),
117
         'delete_published_posts' => array( 'administrator', 'editor', 'author' ),
118
119
         'edit_posts'             => array( 'administrator', 'editor', 'author', 'contributor' ),
120
         'delete_posts'           => array( 'administrator', 'editor', 'author', 'contributor' ),
121
122
         'read'                   => array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ),
123
124
         'level_10'               => array( 'administrator' ),
125
         'level_9'                => array( 'administrator' ),
126
         'level_8'                => array( 'administrator' ),
127
         'level_7'                => array( 'administrator', 'editor' ),
128
         'level_6'                => array( 'administrator', 'editor' ),
129
         'level_5'                => array( 'administrator', 'editor' ),
130
         'level_4'                => array( 'administrator', 'editor' ),
131
         'level_3'                => array( 'administrator', 'editor' ),
132
         'level_2'                => array( 'administrator', 'editor', 'author' ),
133
         'level_1'                => array( 'administrator', 'editor', 'author', 'contributor' ),
134
         'level_0'                => array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ),
135
136
         'administrator'          => array( 'administrator' ),
137
         'editor'                 => array( 'editor' ),
138
         'author'                 => array( 'author' ),
139
         'contributor'            => array( 'contributor' ),
140
         'subscriber'             => array( 'subscriber' ),
141
142
        );
143
144
    }
145
146
    final private function _getMultiSitePrimitiveCaps() 
0 ignored issues
show
Coding Style introduced by
The function name _getMultiSitePrimitiveCaps is in camel caps, but expected _get_multi_site_primitive_caps instead as per the coding standard.
Loading history...
147
    {
148
        return array(
149
150
         'unfiltered_html'        => array(),
151
152
         'activate_plugins'       => array(),
153
         'create_users'           => array(),
154
         'delete_plugins'         => array(),
155
         'delete_themes'          => array(),
156
         'delete_users'           => array(),
157
         'edit_files'             => array(),
158
         'edit_plugins'           => array(),
159
         'edit_themes'            => array(),
160
         'edit_users'             => array(),
161
         'install_plugins'        => array(),
162
         'install_themes'         => array(),
163
         'update_core'            => array(),
164
         'update_plugins'         => array(),
165
         'update_themes'          => array(),
166
167
         'edit_theme_options'     => array( 'administrator' ),
168
         'export'                 => array( 'administrator' ),
169
         'import'                 => array( 'administrator' ),
170
         'list_users'             => array( 'administrator' ),
171
         'manage_options'         => array( 'administrator' ),
172
         'promote_users'          => array( 'administrator' ),
173
         'remove_users'           => array( 'administrator' ),
174
         'switch_themes'          => array( 'administrator' ),
175
         'edit_dashboard'         => array( 'administrator' ),
176
177
         'moderate_comments'      => array( 'administrator', 'editor' ),
178
         'manage_categories'      => array( 'administrator', 'editor' ),
179
         'edit_others_posts'      => array( 'administrator', 'editor' ),
180
         'edit_pages'             => array( 'administrator', 'editor' ),
181
         'edit_others_pages'      => array( 'administrator', 'editor' ),
182
         'edit_published_pages'   => array( 'administrator', 'editor' ),
183
         'publish_pages'          => array( 'administrator', 'editor' ),
184
         'delete_pages'           => array( 'administrator', 'editor' ),
185
         'delete_others_pages'    => array( 'administrator', 'editor' ),
186
         'delete_published_pages' => array( 'administrator', 'editor' ),
187
         'delete_others_posts'    => array( 'administrator', 'editor' ),
188
         'delete_private_posts'   => array( 'administrator', 'editor' ),
189
         'edit_private_posts'     => array( 'administrator', 'editor' ),
190
         'read_private_posts'     => array( 'administrator', 'editor' ),
191
         'delete_private_pages'   => array( 'administrator', 'editor' ),
192
         'edit_private_pages'     => array( 'administrator', 'editor' ),
193
         'read_private_pages'     => array( 'administrator', 'editor' ),
194
195
         'edit_published_posts'   => array( 'administrator', 'editor', 'author' ),
196
         'upload_files'           => array( 'administrator', 'editor', 'author' ),
197
         'publish_posts'          => array( 'administrator', 'editor', 'author' ),
198
         'delete_published_posts' => array( 'administrator', 'editor', 'author' ),
199
200
         'edit_posts'             => array( 'administrator', 'editor', 'author', 'contributor' ),
201
         'delete_posts'           => array( 'administrator', 'editor', 'author', 'contributor' ),
202
203
         'read'                   => array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ),
204
205
         'level_10'               => array( 'administrator' ),
206
         'level_9'                => array( 'administrator' ),
207
         'level_8'                => array( 'administrator' ),
208
         'level_7'                => array( 'administrator', 'editor' ),
209
         'level_6'                => array( 'administrator', 'editor' ),
210
         'level_5'                => array( 'administrator', 'editor' ),
211
         'level_4'                => array( 'administrator', 'editor' ),
212
         'level_3'                => array( 'administrator', 'editor' ),
213
         'level_2'                => array( 'administrator', 'editor', 'author' ),
214
         'level_1'                => array( 'administrator', 'editor', 'author', 'contributor' ),
215
         'level_0'                => array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ),
216
217
         'administrator'          => array( 'administrator' ),
218
         'editor'                 => array( 'editor' ),
219
         'author'                 => array( 'author' ),
220
         'contributor'            => array( 'contributor' ),
221
         'subscriber'             => array( 'subscriber' ),
222
223
        );
224
225
    }
226
227
    final private function _getSingleSiteMetaCaps() 
0 ignored issues
show
Coding Style introduced by
The function name _getSingleSiteMetaCaps is in camel caps, but expected _get_single_site_meta_caps instead as per the coding standard.
Loading history...
228
    {
229
        return array(
230
         'create_sites'           => array(),
231
         'delete_sites'           => array(),
232
         'manage_network'         => array(),
233
         'manage_sites'           => array(),
234
         'manage_network_users'   => array(),
235
         'manage_network_plugins' => array(),
236
         'manage_network_themes'  => array(),
237
         'manage_network_options' => array(),
238
         'delete_site'            => array(),
239
240
         'upload_plugins'         => array( 'administrator' ),
241
         'upload_themes'          => array( 'administrator' ),
242
         'customize'              => array( 'administrator' ),
243
         'add_users'              => array( 'administrator' ),
244
245
         'edit_categories'        => array( 'administrator', 'editor' ),
246
         'delete_categories'      => array( 'administrator', 'editor' ),
247
         'manage_post_tags'       => array( 'administrator', 'editor' ),
248
         'edit_post_tags'         => array( 'administrator', 'editor' ),
249
         'delete_post_tags'       => array( 'administrator', 'editor' ),
250
         'edit_css'               => array( 'administrator', 'editor' ),
251
252
         'assign_categories'      => array( 'administrator', 'editor', 'author', 'contributor' ),
253
         'assign_post_tags'       => array( 'administrator', 'editor', 'author', 'contributor' ),
254
        );
255
    }
256
257
    final private function _getMultiSiteMetaCaps() 
0 ignored issues
show
Coding Style introduced by
The function name _getMultiSiteMetaCaps is in camel caps, but expected _get_multi_site_meta_caps instead as per the coding standard.
Loading history...
258
    {
259
        return array(
260
         'create_sites'           => array(),
261
         'delete_sites'           => array(),
262
         'manage_network'         => array(),
263
         'manage_sites'           => array(),
264
         'manage_network_users'   => array(),
265
         'manage_network_plugins' => array(),
266
         'manage_network_themes'  => array(),
267
         'manage_network_options' => array(),
268
         'upload_plugins'         => array(),
269
         'upload_themes'          => array(),
270
         'edit_css'               => array(),
271
272
         'customize'              => array( 'administrator' ),
273
         'delete_site'            => array( 'administrator' ),
274
         'add_users'              => array( 'administrator' ),
275
276
         'edit_categories'        => array( 'administrator', 'editor' ),
277
         'delete_categories'      => array( 'administrator', 'editor' ),
278
         'manage_post_tags'       => array( 'administrator', 'editor' ),
279
         'edit_post_tags'         => array( 'administrator', 'editor' ),
280
         'delete_post_tags'       => array( 'administrator', 'editor' ),
281
282
         'assign_categories'      => array( 'administrator', 'editor', 'author', 'contributor' ),
283
         'assign_post_tags'       => array( 'administrator', 'editor', 'author', 'contributor' ),
284
        );
285
    }
286
287
    protected function getAllCapsAndRoles() 
0 ignored issues
show
Coding Style introduced by
The function name getAllCapsAndRoles is in camel caps, but expected get_all_caps_and_roles instead as per the coding standard.
Loading history...
288
    {
289
        return $this->getPrimitiveCapsAndRoles() + $this->getMetaCapsAndRoles();
290
    }
291
292
    protected function getPrimitiveCapsAndRoles() 
0 ignored issues
show
Coding Style introduced by
The function name getPrimitiveCapsAndRoles is in camel caps, but expected get_primitive_caps_and_roles instead as per the coding standard.
Loading history...
293
    {
294
        if (is_multisite() ) {
295
            return $this->_getMultiSitePrimitiveCaps();
296
        } else {
297
            return $this->_getSingleSitePrimitiveCaps();
298
        }
299
    }
300
301
    protected function getMetaCapsAndRoles() 
0 ignored issues
show
Coding Style introduced by
The function name getMetaCapsAndRoles is in camel caps, but expected get_meta_caps_and_roles instead as per the coding standard.
Loading history...
302
    {
303
        if (is_multisite() ) {
304
            return $this->_getMultiSiteMetaCaps();
305
        } else {
306
            return $this->_getSingleSiteMetaCaps();
307
        }
308
    }
309
310
    // test the tests
311
    function test_single_and_multisite_cap_tests_match() 
312
    {
313
        $single_primitive = array_keys($this->_getSingleSitePrimitiveCaps());
314
        $multi_primitive  = array_keys($this->_getMultiSitePrimitiveCaps());
315
        sort($single_primitive);
316
        sort($multi_primitive);
317
        $this->assertEquals($single_primitive, $multi_primitive);
318
319
        $single_meta = array_keys($this->_getSingleSiteMetaCaps());
320
        $multi_meta  = array_keys($this->_getMultiSiteMetaCaps());
321
        sort($single_meta);
322
        sort($multi_meta);
323
        $this->assertEquals($single_meta, $multi_meta);
324
    }
325
326
    // test the tests
327
    function test_all_caps_of_users_are_being_tested() 
328
    {
329
        $caps = $this->getPrimitiveCapsAndRoles();
330
331
        // `manage_links` is a special case
332
        $this->assertSame('0', get_option('link_manager_enabled'));
333
        // `unfiltered_upload` is a special case
334
        $this->assertFalse(defined('ALLOW_UNFILTERED_UPLOADS'));
335
336
        foreach ( self::$users as $role => $user ) {
337
338
            // make sure the user is valid
339
            $this->assertTrue($user->exists(), "User with {$role} role does not exist");
340
341
            $user_caps = $user->allcaps;
342
343
            unset(
344
                // `manage_links` is a special case
345
                $user_caps['manage_links'],
346
                // `unfiltered_upload` is a special case
347
                $user_caps['unfiltered_upload']
348
            );
349
350
            $diff = array_diff(array_keys($user_caps), array_keys($caps));
351
352
            $this->assertEquals(array(), $diff, "User with {$role} role has capabilities that aren't being tested");
353
354
        }
355
356
    }
357
358
    /**
359
     * Test the tests. The administrator role has all primitive capabilities, therefore the
360
     * primitive capabilitity tests can be tested by checking that the list of tested
361
     * capabilities matches those of the administrator role.
362
     *
363
     * @group capTestTests
364
     */
365
    public function testPrimitiveCapsTestsAreCorrect() 
0 ignored issues
show
Coding Style introduced by
The function name testPrimitiveCapsTestsAreCorrect is in camel caps, but expected test_primitive_caps_tests_are_correct instead as per the coding standard.
Loading history...
366
    {
367
        $actual   = $this->getPrimitiveCapsAndRoles();
368
        $admin    = get_role('administrator');
369
        $expected = $admin->capabilities;
370
371
        unset(
372
            // Role names as capabilities are a special case:
373
            $actual['administrator'],
374
            $actual['editor'],
375
            $actual['author'],
376
            $actual['subscriber'],
377
            $actual['contributor']
378
        );
379
380
        unset(
381
            // `manage_links` is a special case in the caps tests:
382
            $expected['manage_links'],
383
            // `unfiltered_upload` is a special case in the caps tests:
384
            $expected['unfiltered_upload']
385
        );
386
387
        $expected = array_keys($expected);
388
        $actual   = array_keys($actual);
389
390
        $missing_primitive_cap_checks = array_diff($expected, $actual);
391
        $this->assertSame(array(), $missing_primitive_cap_checks, 'These primitive capabilities are not tested');
392
393
        $incorrect_primitive_cap_checks = array_diff($actual, $expected);
394
        $this->assertSame(array(), $incorrect_primitive_cap_checks, 'These capabilities are not primitive');
395
    }
396
397
    /**
398
     * Test the tests. All meta capabilities should have a condition in the `map_meta_cap()`
399
     * function that handles the capability.
400
     *
401
     * @group capTestTests
402
     */
403
    public function testMetaCapsTestsAreCorrect() 
0 ignored issues
show
Coding Style introduced by
The function name testMetaCapsTestsAreCorrect is in camel caps, but expected test_meta_caps_tests_are_correct instead as per the coding standard.
Loading history...
404
    {
405
        $actual = $this->getMetaCapsAndRoles();
406
        $file   = file_get_contents(ABSPATH . WPINC . '/capabilities.php');
0 ignored issues
show
introduced by
file_get_contents is highly discouraged, please use wpcom_vip_file_get_contents() instead.
Loading history...
407
408
        $matched = preg_match('/^function map_meta_cap\((.*?)^\}/ms', $file, $function);
409
        $this->assertSame(1, $matched);
410
        $this->assertNotEmpty($function);
411
412
        $matched = preg_match_all('/^[\t]case \'([^\']+)/m', $function[0], $cases);
413
        $this->assertNotEmpty($matched);
414
        $this->assertNotEmpty($cases);
415
416
        $expected = array_flip($cases[1]);
417
418
        unset(
419
            // These primitive capabilities have a 'case' in `map_meta_cap()` but aren't meta capabilities:
420
            $expected['unfiltered_upload'],
421
            $expected['unfiltered_html'],
422
            $expected['edit_files'],
423
            $expected['edit_plugins'],
424
            $expected['edit_themes'],
425
            $expected['update_plugins'],
426
            $expected['delete_plugins'],
427
            $expected['install_plugins'],
428
            $expected['update_themes'],
429
            $expected['delete_themes'],
430
            $expected['install_themes'],
431
            $expected['update_core'],
432
            $expected['activate_plugins'],
433
            $expected['edit_users'],
434
            $expected['delete_users'],
435
            $expected['create_users'],
436
            $expected['manage_links'],
437
            // Singular object meta capabilities (where an object ID is passed) are not tested:
438
            $expected['remove_user'],
439
            $expected['promote_user'],
440
            $expected['edit_user'],
441
            $expected['delete_post'],
442
            $expected['delete_page'],
443
            $expected['edit_post'],
444
            $expected['edit_page'],
445
            $expected['read_post'],
446
            $expected['read_page'],
447
            $expected['publish_post'],
448
            $expected['edit_post_meta'],
449
            $expected['delete_post_meta'],
450
            $expected['add_post_meta'],
451
            $expected['edit_comment'],
452
            $expected['edit_comment_meta'],
453
            $expected['delete_comment_meta'],
454
            $expected['add_comment_meta'],
455
            $expected['edit_term'],
456
            $expected['delete_term'],
457
            $expected['assign_term'],
458
            $expected['edit_term_meta'],
459
            $expected['delete_term_meta'],
460
            $expected['add_term_meta'],
461
            $expected['delete_user'],
462
            $expected['edit_user_meta'],
463
            $expected['delete_user_meta'],
464
            $expected['add_user_meta']
465
        );
466
467
        $expected = array_keys($expected);
468
        $actual   = array_keys($actual);
469
470
        $missing_meta_cap_checks = array_diff($expected, $actual);
471
        $this->assertSame(array(), $missing_meta_cap_checks, 'These meta capabilities are not tested');
472
473
        $incorrect_meta_cap_checks = array_diff($actual, $expected);
474
        $this->assertSame(array(), $incorrect_meta_cap_checks, 'These capabilities are not meta');
475
    }
476
477
    // test the default roles and caps
478
    function test_all_roles_and_caps() 
479
    {
480
        $caps = $this->getAllCapsAndRoles();
481
482
        foreach ( self::$users as $role => $user ) {
483
484
            // make sure the user is valid
485
            $this->assertTrue($user->exists(), "User with {$role} role does not exist");
486
487
            // make sure the role name is correct
488
            $this->assertEquals(array( $role ), $user->roles, "User should only have the {$role} role");
489
490 View Code Duplication
            foreach ( $caps as $cap => $roles ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
491
                if (in_array($role, $roles, true) ) {
492
                    $this->assertTrue($user->has_cap($cap), "User with the {$role} role should have the {$cap} capability");
493
                    $this->assertTrue(user_can($user, $cap), "User with the {$role} role should have the {$cap} capability");
494
                } else {
495
                    $this->assertFalse($user->has_cap($cap), "User with the {$role} role should not have the {$cap} capability");
496
                    $this->assertFalse(user_can($user, $cap), "User with the {$role} role should not have the {$cap} capability");
497
                }
498
            }
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
499
500
        }
501
502
        $this->assertFalse($user->has_cap('start_a_fire'), "User with the {$role} role should not have a custom capability");
0 ignored issues
show
Bug introduced by
The variable $user seems to be defined by a foreach iteration on line 482. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
Bug introduced by
The variable $role seems to be defined by a foreach iteration on line 482. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
503
        $this->assertFalse(user_can($user, 'start_a_fire'), "User with the {$role} role should not have a custom capability");
504
505
        $this->assertFalse($user->has_cap('do_not_allow'), "User with the {$role} role should not have the do_not_allow capability");
506
        $this->assertFalse(user_can($user, 'do_not_allow'), "User with the {$role} role should not have the do_not_allow capability");
507
508
        $this->assertTrue($user->has_cap('exist'), "User with the {$role} role should have the exist capability");
509
        $this->assertTrue(user_can($user, 'exist'), "User with the {$role} role should have the exist capability");
510
    }
511
512
    // special case for the link manager
513
    function test_link_manager_caps() 
514
    {
515
        $caps = array(
516
         'manage_links' => array( 'administrator', 'editor' ),
517
        );
518
519
        $this->assertSame('0', get_option('link_manager_enabled'));
520
521
        // no-one should have access to the link manager by default
522 View Code Duplication
        foreach ( self::$users as $role => $user ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
523
            foreach ( $caps as $cap => $roles ) {
524
                $this->assertFalse($user->has_cap($cap), "User with the {$role} role should not have the {$cap} capability");
525
                $this->assertFalse(user_can($user, $cap), "User with the {$role} role should not have the {$cap} capability");
526
            }
527
        }
528
529
        update_option('link_manager_enabled', '1');
530
        $this->assertSame('1', get_option('link_manager_enabled'));
531
532 View Code Duplication
        foreach ( self::$users as $role => $user ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
533
            foreach ( $caps as $cap => $roles ) {
534
                if (in_array($role, $roles, true) ) {
535
                    $this->assertTrue($user->has_cap($cap), "User with the {$role} role should have the {$cap} capability");
536
                    $this->assertTrue(user_can($user, $cap), "User with the {$role} role should have the {$cap} capability");
537
                } else {
538
                    $this->assertFalse($user->has_cap($cap), "User with the {$role} role should not have the {$cap} capability");
539
                    $this->assertFalse(user_can($user, $cap), "User with the {$role} role should not have the {$cap} capability");
540
                }
541
            }
542
        }
543
544
        update_option('link_manager_enabled', '0');
545
        $this->assertSame('0', get_option('link_manager_enabled'));
546
547
    }
548
549
    // special case for unfiltered uploads
550
    function test_unfiltered_upload_caps() 
551
    {
552
        $this->assertFalse(defined('ALLOW_UNFILTERED_UPLOADS'));
553
554
        // no-one should have this cap
555
        foreach ( self::$users as $role => $user ) {
556
            $this->assertFalse($user->has_cap('unfiltered_upload'), "User with the {$role} role should not have the unfiltered_upload capability");
557
            $this->assertFalse(user_can($user, 'unfiltered_upload'), "User with the {$role} role should not have the unfiltered_upload capability");
558
        }
559
560
    }
561
562
    /**
563
     * @dataProvider data_user_with_role_can_edit_own_post
564
     *
565
     * @param  string $role              User role name
566
     * @param  bool   $can_edit_own_post Can users with this role edit their own posts?
567
     */
568
    public function test_user_can_edit_comment_on_own_post( $role, $can_edit_own_post ) 
569
    {
570
        $owner   = self::$users[ $role ];
571
        $post    = self::factory()->post->create_and_get(
572
            array(
573
            'post_author' => $owner->ID,
574
            ) 
575
        );
576
        $comment = self::factory()->comment->create_and_get(
577
            array(
578
            'comment_post_ID' => $post->ID,
579
            ) 
580
        );
581
582
        $owner_can_edit = user_can($owner->ID, 'edit_comment', $comment->comment_ID);
583
        $this->assertSame($can_edit_own_post, $owner_can_edit);
584
    }
585
586
    /**
587
     * @dataProvider data_user_with_role_can_edit_others_posts
588
     *
589
     * @param  string $role                 User role name
590
     * @param  bool   $can_edit_others_post Can users with this role edit others' posts?
591
     */
592
    public function test_user_can_edit_comment_on_others_post( $role, $can_edit_others_post ) 
593
    {
594
        $user    = self::$users[ $role ];
595
        $owner   = self::factory()->user->create_and_get(
596
            array(
597
            'role' => 'editor',
598
            ) 
599
        );
600
        $post    = self::factory()->post->create_and_get(
601
            array(
602
            'post_author' => $owner->ID,
603
            ) 
604
        );
605
        $comment = self::factory()->comment->create_and_get(
606
            array(
607
            'comment_post_ID' => $post->ID,
608
            ) 
609
        );
610
611
        $user_can_edit = user_can($user->ID, 'edit_comment', $comment->comment_ID);
612
        $this->assertSame($can_edit_others_post, $user_can_edit);
613
    }
614
615 View Code Duplication
    public function data_user_with_role_can_edit_own_post() 
616
    {
617
        $data  = array();
618
        $caps  = $this->getPrimitiveCapsAndRoles();
619
620
        foreach ( self::$users as $role => $null ) {
621
            $data[] = array(
622
             $role,
623
             in_array($role, $caps['edit_published_posts'], true),
624
            );
625
        }
626
627
        return $data;
628
    }
629
630 View Code Duplication
    public function data_user_with_role_can_edit_others_posts() 
631
    {
632
        $data  = array();
633
        $caps  = $this->getPrimitiveCapsAndRoles();
634
635
        foreach ( self::$users as $role => $null ) {
636
            $data[] = array(
637
             $role,
638
             in_array($role, $caps['edit_others_posts'], true),
639
            );
640
        }
641
642
        return $data;
643
    }
644
645
    function test_super_admin_caps() 
646
    {
647
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
648
            $this->markTestSkipped('Test only runs in multisite');
649
            return;
650
        }
651
        $caps = $this->getAllCapsAndRoles();
652
        $user = self::$super_admin;
653
654
        $this->assertTrue(is_super_admin($user->ID));
655
656
        foreach ( $caps as $cap => $roles ) {
657
            $this->assertTrue($user->has_cap($cap), "Super Admins should have the {$cap} capability");
658
            $this->assertTrue(user_can($user, $cap), "Super Admins should have the {$cap} capability");
659
        }
660
661
        $this->assertTrue($user->has_cap('start_a_fire'), "Super admins should have all custom capabilities");
662
        $this->assertTrue(user_can($user, 'start_a_fire'), "Super admins should have all custom capabilities");
663
664
        $this->assertFalse($user->has_cap('do_not_allow'), 'Super Admins should not have the do_not_allow capability');
665
        $this->assertFalse(user_can($user, 'do_not_allow'), 'Super Admins should not have the do_not_allow capability');
666
667
        $this->assertFalse(defined('ALLOW_UNFILTERED_UPLOADS'));
668
        $this->assertFalse($user->has_cap('unfiltered_upload'), 'Super Admins should not have the unfiltered_upload capability');
669
        $this->assertFalse(user_can($user, 'unfiltered_upload'), 'Super Admins should not have the unfiltered_upload capability');
670
    }
671
672
    // a role that doesn't exist
673
    function test_bogus_role() 
674
    {
675
        $user = self::factory()->user->create_and_get(array( 'role' => 'invalid_role' ));
676
677
        // make sure the user is valid
678
        $this->assertTrue($user->exists(), "User does not exist");
679
680
        // make sure the role name is correct
681
        $this->assertEquals(array(), $user->roles, "User should not have any roles");
682
683
        $caps = $this->getAllCapsAndRoles();
684
685 View Code Duplication
        foreach ( $caps as $cap => $roles ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
686
            $this->assertFalse($user->has_cap($cap), "User with an invalid role should not have the {$cap} capability");
687
            $this->assertFalse(user_can($user, $cap), "User with an invalid role should not have the {$cap} capability");
688
        }
689
    }
690
691
    // a user with multiple roles
692
    function test_user_subscriber_contributor() 
693
    {
694
        $user = self::$users['subscriber'];
695
696
        // make sure the user is valid
697
        $this->assertTrue($user->exists(), "User does not exist");
698
699
        $user->add_role('contributor');
700
701
        // user should have two roles now
702
        $this->assertEquals(array( 'subscriber', 'contributor' ), $user->roles);
703
704
        $caps = $this->getAllCapsAndRoles();
705
706 View Code Duplication
        foreach ( $caps as $cap => $roles ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
707
            if (array_intersect($user->roles, $roles) ) {
708
                $this->assertTrue($user->has_cap($cap), "User should have the {$cap} capability");
709
                $this->assertTrue(user_can($user, $cap), "User should have the {$cap} capability");
710
            } else {
711
                $this->assertFalse($user->has_cap($cap), "User should not have the {$cap} capability");
712
                $this->assertFalse(user_can($user, $cap), "User should not have the {$cap} capability");
713
            }
714
        }
715
716
        $user->remove_role('contributor');
717
        // user should have one role now
718
        $this->assertEquals(array( 'subscriber' ), $user->roles);
719
720
    }
721
722
    // newly added empty role
723
    function test_add_empty_role() 
724
    {
725
        global $wp_roles;
726
727
        $role_name = 'janitor';
728
        add_role($role_name, 'Janitor', array());
0 ignored issues
show
introduced by
Use wpcom_vip_add_role() instead of add_role()
Loading history...
729
730
        $this->_flush_roles();
731
        $this->assertTrue($wp_roles->is_role($role_name));
732
733
        $user = self::factory()->user->create_and_get(array( 'role' => $role_name ));
734
735
        // make sure the user is valid
736
        $this->assertTrue($user->exists(), "User does not exist");
737
738
        // make sure the role name is correct
739
        $this->assertEquals(array( $role_name ), $user->roles);
740
741
        $caps = $this->getAllCapsAndRoles();
742
743 View Code Duplication
        foreach ( $caps as $cap => $roles ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
744
            $this->assertFalse($user->has_cap($cap), "User should not have the {$cap} capability");
745
            $this->assertFalse(user_can($user, $cap), "User should not have the {$cap} capability");
746
        }
747
748
        // clean up
749
        remove_role($role_name);
750
        $this->_flush_roles();
751
        $this->assertFalse($wp_roles->is_role($role_name));
752
    }
753
754
    // newly added role
755
    function test_add_role() 
756
    {
757
        global $wp_roles;
758
759
        $role_name = 'janitor';
760
        $expected_caps = array(
761
         'edit_posts' => true,
762
         'edit_pages' => true,
763
         'level_0'    => true,
764
         'level_1'    => true,
765
         'level_2'    => true,
766
        );
767
        add_role($role_name, 'Janitor', $expected_caps);
0 ignored issues
show
introduced by
Use wpcom_vip_add_role() instead of add_role()
Loading history...
768
        $this->_flush_roles();
769
        $this->assertTrue($wp_roles->is_role($role_name));
770
771
        $user = self::factory()->user->create_and_get(array( 'role' => $role_name ));
772
773
        // make sure the user is valid
774
        $this->assertTrue($user->exists(), "User does not exist");
775
776
        // make sure the role name is correct
777
        $this->assertEquals(array( $role_name ), $user->roles);
778
779
        $caps = $this->getPrimitiveCapsAndRoles();
780
781 View Code Duplication
        foreach ( $caps as $cap => $roles ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
782
               // the user should have all the above caps
783
            if (isset($expected_caps[ $cap ]) ) {
784
                $this->assertTrue($user->has_cap($cap), "User should have the {$cap} capability");
785
                $this->assertTrue(user_can($user, $cap), "User should have the {$cap} capability");
786
            } else {
787
                 $this->assertFalse($user->has_cap($cap), "User should not have the {$cap} capability");
788
                 $this->assertFalse(user_can($user, $cap), "User should not have the {$cap} capability");
789
            }
790
        }
791
792
        // clean up
793
        remove_role($role_name);
794
        $this->_flush_roles();
795
        $this->assertFalse($wp_roles->is_role($role_name));
796
    }
797
798
    function test_role_add_cap() 
799
    {
800
        // change the capabilites associated with a role and make sure the change is reflected in has_cap()
801
802
        global $wp_roles;
803
        $role_name = 'janitor';
804
        add_role($role_name, 'Janitor', array('level_1'=>true));
0 ignored issues
show
introduced by
Use wpcom_vip_add_role() instead of add_role()
Loading history...
introduced by
Expected 1 space before "=>"; 0 found
Loading history...
introduced by
Expected 1 space after "=>"; 0 found
Loading history...
805
        $this->_flush_roles();
806
        $this->assertTrue($wp_roles->is_role($role_name));
807
808
        // assign a user to that role
809
        $id = self::factory()->user->create(array( 'role' => $role_name ));
810
811
        // now add a cap to the role
812
        $wp_roles->add_cap($role_name, 'sweep_floor');
813
        $this->_flush_roles();
814
815
        $user = new WP_User($id);
816
        $this->assertTrue($user->exists(), "Problem getting user $id");
817
        $this->assertEquals(array($role_name), $user->roles);
818
819
        // the user should have all the above caps
820
        $this->assertTrue($user->has_cap($role_name));
821
        $this->assertTrue($user->has_cap('level_1'));
822
        $this->assertTrue($user->has_cap('sweep_floor'));
823
824
        // shouldn't have any other caps
825
        $caps = $this->getAllCapsAndRoles();
826
        foreach ( $caps as $cap => $roles ) {
827
            if ('level_1' !== $cap ) {
828
                $this->assertFalse($user->has_cap($cap), "User should not have the {$cap} capability");
829
            }
830
        }
831
832
        // clean up
833
        remove_role($role_name);
834
        $this->_flush_roles();
835
        $this->assertFalse($wp_roles->is_role($role_name));
836
837
    }
838
839
    function test_role_remove_cap() 
840
    {
841
        // change the capabilites associated with a role and make sure the change is reflected in has_cap()
842
843
        global $wp_roles;
844
        $role_name = 'janitor';
845
        add_role($role_name, 'Janitor', array('level_1'=>true, 'sweep_floor'=>true, 'polish_doorknobs'=>true));
0 ignored issues
show
introduced by
Use wpcom_vip_add_role() instead of add_role()
Loading history...
introduced by
Expected 1 space before "=>"; 0 found
Loading history...
introduced by
Expected 1 space after "=>"; 0 found
Loading history...
846
        $this->_flush_roles();
847
        $this->assertTrue($wp_roles->is_role($role_name));
848
849
        // assign a user to that role
850
        $id = self::factory()->user->create(array( 'role' => $role_name ));
851
852
        // now remove a cap from the role
853
        $wp_roles->remove_cap($role_name, 'polish_doorknobs');
854
        $this->_flush_roles();
855
856
        $user = new WP_User($id);
857
        $this->assertTrue($user->exists(), "Problem getting user $id");
858
        $this->assertEquals(array($role_name), $user->roles);
859
860
        // the user should have all the above caps
861
        $this->assertTrue($user->has_cap($role_name));
862
        $this->assertTrue($user->has_cap('level_1'));
863
        $this->assertTrue($user->has_cap('sweep_floor'));
864
865
        // shouldn't have the removed cap
866
        $this->assertFalse($user->has_cap('polish_doorknobs'));
867
868
        // clean up
869
        remove_role($role_name);
870
        $this->_flush_roles();
871
        $this->assertFalse($wp_roles->is_role($role_name));
872
873
    }
874
875
    function test_user_add_cap() 
876
    {
877
        // add an extra capability to a user
878
879
        // there are two contributors
880
        $id_1 = self::factory()->user->create(array( 'role' => 'contributor' ));
881
        $id_2 = self::factory()->user->create(array( 'role' => 'contributor' ));
882
883
        // user 1 has an extra capability
884
        $user_1 = new WP_User($id_1);
885
        $this->assertTrue($user_1->exists(), "Problem getting user $id_1");
886
        $user_1->add_cap('publish_posts');
887
888
        // re-fetch both users from the db
889
        $user_1 = new WP_User($id_1);
890
        $this->assertTrue($user_1->exists(), "Problem getting user $id_1");
891
        $user_2 = new WP_User($id_2);
892
        $this->assertTrue($user_2->exists(), "Problem getting user $id_2");
893
894
        // make sure they're both still contributors
895
        $this->assertEquals(array('contributor'), $user_1->roles);
896
        $this->assertEquals(array('contributor'), $user_2->roles);
897
898
        // check the extra cap on both users
899
        $this->assertTrue($user_1->has_cap('publish_posts'));
900
        $this->assertFalse($user_2->has_cap('publish_posts'));
901
902
        // make sure the other caps didn't get messed up
903
        $caps = $this->getAllCapsAndRoles();
904
        foreach ( $caps as $cap => $roles ) {
905
            if (in_array('contributor', $roles, true) || 'publish_posts' === $cap ) {
906
                $this->assertTrue($user_1->has_cap($cap), "User should have the {$cap} capability");
907
            } else {
908
                $this->assertFalse($user_1->has_cap($cap), "User should not have the {$cap} capability");
909
            }
910
        }
911
912
    }
913
914
    function test_user_remove_cap() 
915
    {
916
        // add an extra capability to a user then remove it
917
918
        // there are two contributors
919
        $id_1 = self::factory()->user->create(array( 'role' => 'contributor' ));
920
        $id_2 = self::factory()->user->create(array( 'role' => 'contributor' ));
921
922
        // user 1 has an extra capability
923
        $user_1 = new WP_User($id_1);
924
        $this->assertTrue($user_1->exists(), "Problem getting user $id_1");
925
        $user_1->add_cap('publish_posts');
926
927
        // now remove the extra cap
928
        $user_1->remove_cap('publish_posts');
929
930
        // re-fetch both users from the db
931
        $user_1 = new WP_User($id_1);
932
        $this->assertTrue($user_1->exists(), "Problem getting user $id_1");
933
        $user_2 = new WP_User($id_2);
934
        $this->assertTrue($user_2->exists(), "Problem getting user $id_2");
935
936
        // make sure they're both still contributors
937
        $this->assertEquals(array('contributor'), $user_1->roles);
938
        $this->assertEquals(array('contributor'), $user_2->roles);
939
940
        // check the removed cap on both users
941
        $this->assertFalse($user_1->has_cap('publish_posts'));
942
        $this->assertFalse($user_2->has_cap('publish_posts'));
943
944
    }
945
946
    function test_user_level_update() 
947
    {
948
        // make sure the user_level is correctly set and changed with the user's role
949
950
        // user starts as an author
951
        $id = self::factory()->user->create(array( 'role' => 'author' ));
952
        $user = new WP_User($id);
953
        $this->assertTrue($user->exists(), "Problem getting user $id");
954
955
        // author = user level 2
956
        $this->assertEquals(2, $user->user_level);
957
958
        // they get promoted to editor - level should get bumped to 7
959
        $user->set_role('editor');
960
        $this->assertEquals(7, $user->user_level);
961
962
        // demoted to contributor - level is reduced to 1
963
        $user->set_role('contributor');
964
        $this->assertEquals(1, $user->user_level);
965
966
        // if they have two roles, user_level should be the max of the two
967
        $user->add_role('editor');
968
        $this->assertEquals(array('contributor', 'editor'), $user->roles);
969
        $this->assertEquals(7, $user->user_level);
970
    }
971
972
    function test_user_remove_all_caps() 
973
    {
974
        // user starts as an author
975
        $id = self::factory()->user->create(array( 'role' => 'author' ));
976
        $user = new WP_User($id);
977
        $this->assertTrue($user->exists(), "Problem getting user $id");
978
979
        // add some extra capabilities
980
        $user->add_cap('make_coffee');
981
        $user->add_cap('drink_coffee');
982
983
        // re-fetch
984
        $user = new WP_User($id);
985
        $this->assertTrue($user->exists(), "Problem getting user $id");
986
987
        $this->assertTrue($user->has_cap('make_coffee'));
988
        $this->assertTrue($user->has_cap('drink_coffee'));
989
990
        // all caps are removed
991
        $user->remove_all_caps();
992
993
        // re-fetch
994
        $user = new WP_User($id);
995
        $this->assertTrue($user->exists(), "Problem getting user $id");
996
997
        // all capabilities for the user should be gone
998
        foreach ( $this->getAllCapsAndRoles() as $cap => $roles ) {
999
            $this->assertFalse($user->has_cap($cap), "User should not have the {$cap} capability");
1000
        }
1001
1002
        // the extra capabilities should be gone
1003
        $this->assertFalse($user->has_cap('make_coffee'));
1004
        $this->assertFalse($user->has_cap('drink_coffee'));
1005
1006
        // user level should be empty
1007
        $this->assertEmpty($user->user_level);
1008
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1009
1010
    }
1011
1012
    function test_post_meta_caps() 
1013
    {
1014
        // simple tests for some common meta capabilities
1015
1016
        // Get our author
1017
        $author = self::$users['author'];
1018
1019
        // make a post
1020
        $post = self::factory()->post->create(array( 'post_author' => $author->ID, 'post_type' => 'post' ));
1021
1022
        // the author of the post
1023
        $this->assertTrue($author->exists(), "Problem getting user $author->ID");
1024
1025
        // add some other users
1026
        $admin = new WP_User(self::factory()->user->create(array( 'role' => 'administrator' )));
1027
        $author_2 = new WP_User(self::factory()->user->create(array( 'role' => 'author' )));
1028
        $editor = new WP_User(self::factory()->user->create(array( 'role' => 'editor' )));
1029
        $contributor = new WP_User(self::factory()->user->create(array( 'role' => 'contributor' )));
1030
1031
        // administrators, editors and the post owner can edit it
1032
        $this->assertTrue($admin->has_cap('edit_post', $post));
1033
        $this->assertTrue($author->has_cap('edit_post', $post));
1034
        $this->assertTrue($editor->has_cap('edit_post', $post));
1035
        // other authors and contributors can't
1036
        $this->assertFalse($author_2->has_cap('edit_post', $post));
1037
        $this->assertFalse($contributor->has_cap('edit_post', $post));
1038
1039
        // administrators, editors and the post owner can delete it
1040
        $this->assertTrue($admin->has_cap('delete_post', $post));
1041
        $this->assertTrue($author->has_cap('delete_post', $post));
1042
        $this->assertTrue($editor->has_cap('delete_post', $post));
1043
        // other authors and contributors can't
1044
        $this->assertFalse($author_2->has_cap('delete_post', $post));
1045
        $this->assertFalse($contributor->has_cap('delete_post', $post));
1046
1047
        // administrators, editors, and authors can publish it
1048
        $this->assertTrue($admin->has_cap('publish_post', $post));
1049
        $this->assertTrue($author->has_cap('publish_post', $post));
1050
        $this->assertTrue($editor->has_cap('publish_post', $post));
1051
        $this->assertTrue($author_2->has_cap('publish_post', $post));
1052
        // contributors can't
1053
        $this->assertFalse($contributor->has_cap('publish_post', $post));
1054
1055
        register_post_type('something', array( 'capabilities' => array( 'edit_posts' => 'draw_somethings' ) ));
1056
        $something = get_post_type_object('something');
1057
        $this->assertEquals('draw_somethings', $something->cap->edit_posts);
1058
        $this->assertEquals('draw_somethings', $something->cap->create_posts);
1059
1060
        register_post_type(
1061
            'something', array( 'capabilities' =>
1062
            array( 'edit_posts' => 'draw_somethings', 'create_posts' => 'create_somethings' ) ) 
1063
        );
1064
        $something = get_post_type_object('something');
1065
        $this->assertEquals('draw_somethings', $something->cap->edit_posts);
1066
        $this->assertEquals('create_somethings', $something->cap->create_posts);
1067
        _unregister_post_type('something');
1068
1069
        // Test meta authorization callbacks
1070
        if (function_exists('register_meta') ) {
1071
            $this->assertTrue($admin->has_cap('edit_post_meta',  $post));
1072
            $this->assertTrue($admin->has_cap('add_post_meta',  $post));
1073
            $this->assertTrue($admin->has_cap('delete_post_meta',  $post));
1074
1075
            $this->assertFalse($admin->has_cap('edit_post_meta', $post, '_protected'));
1076
            $this->assertFalse($admin->has_cap('add_post_meta', $post, '_protected'));
1077
            $this->assertFalse($admin->has_cap('delete_post_meta', $post, '_protected'));
1078
1079
            register_meta('post', '_protected', array( $this, '_meta_filter' ), array( $this, '_meta_yes_you_can' ));
1080
            $this->assertTrue($admin->has_cap('edit_post_meta',  $post, '_protected'));
1081
            $this->assertTrue($admin->has_cap('add_post_meta',  $post, '_protected'));
1082
            $this->assertTrue($admin->has_cap('delete_post_meta',  $post, '_protected'));
1083
1084
            $this->assertTrue($admin->has_cap('edit_post_meta', $post, 'not_protected'));
1085
            $this->assertTrue($admin->has_cap('add_post_meta', $post, 'not_protected'));
1086
            $this->assertTrue($admin->has_cap('delete_post_meta', $post, 'not_protected'));
1087
1088
            register_meta('post', 'not_protected', array( $this, '_meta_filter' ), array( $this, '_meta_no_you_cant' ));
1089
            $this->assertFalse($admin->has_cap('edit_post_meta',  $post, 'not_protected'));
1090
            $this->assertFalse($admin->has_cap('add_post_meta',  $post, 'not_protected'));
1091
            $this->assertFalse($admin->has_cap('delete_post_meta',  $post, 'not_protected'));
1092
        }
1093
    }
1094
1095
    function authorless_post_statuses() 
1096
    {
1097
        return array( array( 'draft' ), array( 'private' ), array( 'publish' ) );
1098
    }
1099
1100
    /**
1101
     * @ticket 27020
1102
     * @dataProvider authorless_post_statuses
1103
     */
1104
    function test_authorless_post( $status ) 
1105
    {
1106
        // Make a post without an author
1107
        $post = self::factory()->post->create(array( 'post_author' => 0, 'post_type' => 'post', 'post_status' => $status ));
1108
1109
        // Add an editor and contributor
1110
        $editor = self::$users['editor'];
1111
        $contributor = self::$users['contributor'];
1112
1113
        // editor can publish, edit, view, and trash
1114
        $this->assertTrue($editor->has_cap('publish_post', $post));
1115
        $this->assertTrue($editor->has_cap('edit_post', $post));
1116
        $this->assertTrue($editor->has_cap('delete_post', $post));
1117
        $this->assertTrue($editor->has_cap('read_post', $post));
1118
1119
        // a contributor cannot (except read a published post)
1120
        $this->assertFalse($contributor->has_cap('publish_post', $post));
1121
        $this->assertFalse($contributor->has_cap('edit_post', $post));
1122
        $this->assertFalse($contributor->has_cap('delete_post', $post));
1123
        $this->assertEquals($status === 'publish', $contributor->has_cap('read_post', $post));
1124
    }
1125
1126
    /**
1127
     * @ticket 16714
1128
     */
1129
    function test_create_posts_caps() 
1130
    {
1131
        $admin       = self::$users['administrator'];
1132
        $author      = self::$users['author'];
1133
        $editor      = self::$users['editor'];
1134
        $contributor = self::$users['contributor'];
1135
        $subscriber  = self::$users['subscriber'];
1136
1137
        // create_posts isn't a real cap.
1138
        $this->assertFalse($admin->has_cap('create_posts'));
1139
        $this->assertFalse($author->has_cap('create_posts'));
1140
        $this->assertFalse($editor->has_cap('create_posts'));
1141
        $this->assertFalse($contributor->has_cap('create_posts'));
1142
        $this->assertFalse($subscriber->has_cap('create_posts'));
1143
1144
        register_post_type('foobar');
1145
        $cap = get_post_type_object('foobar')->cap;
1146
1147
        $this->assertEquals('edit_posts', $cap->create_posts);
1148
1149
        $this->assertTrue($admin->has_cap($cap->create_posts));
1150
        $this->assertTrue($author->has_cap($cap->create_posts));
1151
        $this->assertTrue($editor->has_cap($cap->create_posts));
1152
        $this->assertTrue($contributor->has_cap($cap->create_posts));
1153
        $this->assertFalse($subscriber->has_cap($cap->create_posts));
1154
1155
        _unregister_post_type('foobar');
1156
1157
        // Primitive capability edit_foobars is not assigned to any users.
1158
        register_post_type('foobar', array( 'capability_type' => array( 'foobar', 'foobars' ) ));
1159
        $cap = get_post_type_object('foobar')->cap;
1160
1161
        $this->assertEquals('edit_foobars', $cap->create_posts);
1162
1163
        $this->assertFalse($admin->has_cap($cap->create_posts));
1164
        $this->assertFalse($author->has_cap($cap->create_posts));
1165
        $this->assertFalse($editor->has_cap($cap->create_posts));
1166
        $this->assertFalse($contributor->has_cap($cap->create_posts));
1167
        $this->assertFalse($subscriber->has_cap($cap->create_posts));
1168
1169
        // Add edit_foobars primitive cap to a user.
1170
        $admin->add_cap('edit_foobars', true);
1171
        $admin = new WP_User($admin->ID);
1172
        $this->assertTrue($admin->has_cap($cap->create_posts));
1173
        $this->assertFalse($author->has_cap($cap->create_posts));
1174
        $this->assertFalse($editor->has_cap($cap->create_posts));
1175
        $this->assertFalse($contributor->has_cap($cap->create_posts));
1176
        $this->assertFalse($subscriber->has_cap($cap->create_posts));
1177
1178
        $admin->remove_cap('edit_foobars');
1179
1180
        _unregister_post_type('foobar');
1181
1182
        $cap = get_post_type_object('attachment')->cap;
1183
        $this->assertEquals('upload_files', $cap->create_posts);
1184
        $this->assertEquals('edit_posts', $cap->edit_posts);
1185
1186
        $this->assertTrue($author->has_cap($cap->create_posts));
1187
        $this->assertTrue($author->has_cap($cap->edit_posts));
1188
        $this->assertTrue($contributor->has_cap($cap->edit_posts));
1189
        $this->assertFalse($contributor->has_cap($cap->create_posts));
1190
        $this->assertFalse($subscriber->has_cap($cap->create_posts));
1191
    }
1192
1193
    function test_page_meta_caps() 
1194
    {
1195
        // simple tests for some common meta capabilities
1196
1197
        // Get our author
1198
        $author = self::$users['author'];
1199
1200
        // make a page
1201
        $page = self::factory()->post->create(array( 'post_author' => $author->ID, 'post_type' => 'page' ));
1202
1203
        // the author of the page
1204
        $this->assertTrue($author->exists(), "Problem getting user " . $author->ID);
1205
1206
        // add some other users
1207
        $admin = self::$users['administrator'];
1208
        $author_2 = new WP_User(self::factory()->user->create(array( 'role' => 'author' )));
1209
        $editor = self::$users['editor'];
1210
        $contributor = self::$users['contributor'];
1211
1212
        // administrators, editors and the post owner can edit it
1213
        $this->assertTrue($admin->has_cap('edit_page', $page));
1214
        $this->assertTrue($editor->has_cap('edit_page', $page));
1215
        // other authors and contributors can't
1216
        $this->assertFalse($author->has_cap('edit_page', $page));
1217
        $this->assertFalse($author_2->has_cap('edit_page', $page));
1218
        $this->assertFalse($contributor->has_cap('edit_page', $page));
1219
1220
        // administrators, editors and the post owner can delete it
1221
        $this->assertTrue($admin->has_cap('delete_page', $page));
1222
        $this->assertTrue($editor->has_cap('delete_page', $page));
1223
        // other authors and contributors can't
1224
        $this->assertFalse($author->has_cap('delete_page', $page));
1225
        $this->assertFalse($author_2->has_cap('delete_page', $page));
1226
        $this->assertFalse($contributor->has_cap('delete_page', $page));
1227
    }
1228
1229
    /**
1230
     * @dataProvider dataTaxonomies
1231
     *
1232
     * @ticket 35614
1233
     */
1234
    public function test_taxonomy_capabilities_are_correct( $taxonomy ) 
1235
    {
1236
        if (! taxonomy_exists($taxonomy) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1237
            register_taxonomy($taxonomy, 'post');
1238
        }
1239
1240
        $tax  = get_taxonomy($taxonomy);
1241
        $user = self::$users['administrator'];
1242
1243
        // Primitive capabilities for all taxonomies should match this:
1244
        $expected = array(
1245
         'manage_terms' => 'manage_categories',
1246
         'edit_terms'   => 'manage_categories',
1247
         'delete_terms' => 'manage_categories',
1248
         'assign_terms' => 'edit_posts',
1249
        );
1250
1251 View Code Duplication
        foreach ( $expected as $meta_cap => $primitive_cap ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1252
            $caps = map_meta_cap($tax->cap->$meta_cap, $user->ID);
1253
            $this->assertEquals(
1254
                array(
1255
                $primitive_cap,
1256
                ), $caps, "Meta cap: {$meta_cap}" 
1257
            );
1258
        }
1259
    }
1260
1261
    /**
1262
     * @dataProvider dataTaxonomies
1263
     *
1264
     * @ticket 35614
1265
     */
1266
    public function test_default_taxonomy_term_cannot_be_deleted( $taxonomy ) 
1267
    {
1268
        if (! taxonomy_exists($taxonomy) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1269
            register_taxonomy($taxonomy, 'post');
1270
        }
1271
1272
        $tax  = get_taxonomy($taxonomy);
1273
        $user = self::$users['administrator'];
1274
        $term = self::factory()->term->create_and_get(
1275
            array(
1276
            'taxonomy' => $taxonomy,
1277
            ) 
1278
        );
1279
1280
        update_option("default_{$taxonomy}", $term->term_id);
1281
1282
        $this->assertTrue(user_can($user->ID, $tax->cap->delete_terms));
1283
        $this->assertFalse(user_can($user->ID, 'delete_term', $term->term_id));
1284
    }
1285
1286
    /**
1287
     * @dataProvider dataTaxonomies
1288
     *
1289
     * @ticket 35614
1290
     */
1291
    public function test_taxonomy_caps_map_correctly_to_their_meta_cap( $taxonomy ) 
1292
    {
1293
        if (! taxonomy_exists($taxonomy) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1294
            register_taxonomy($taxonomy, 'post');
1295
        }
1296
1297
        $tax  = get_taxonomy($taxonomy);
1298
        $term = self::factory()->term->create_and_get(
1299
            array(
1300
            'taxonomy' => $taxonomy,
1301
            ) 
1302
        );
1303
1304
        foreach ( self::$users as $role => $user ) {
1305
            $this->assertSame(
1306
                user_can($user->ID, 'edit_term', $term->term_id),
1307
                user_can($user->ID, $tax->cap->edit_terms),
1308
                "Role: {$role}"
1309
            );
1310
            $this->assertSame(
1311
                user_can($user->ID, 'delete_term', $term->term_id),
1312
                user_can($user->ID, $tax->cap->delete_terms),
1313
                "Role: {$role}"
1314
            );
1315
            $this->assertSame(
1316
                user_can($user->ID, 'assign_term', $term->term_id),
1317
                user_can($user->ID, $tax->cap->assign_terms),
1318
                "Role: {$role}"
1319
            );
1320
        }
1321
1322
    }
1323
1324
    public function dataTaxonomies() 
0 ignored issues
show
Coding Style introduced by
The function name dataTaxonomies is in camel caps, but expected data_taxonomies instead as per the coding standard.
Loading history...
1325
    {
1326
        return array(
1327
         array(
1328
          'post_tag',
1329
         ),
1330
         array(
1331
          'category',
1332
         ),
1333
         array(
1334
          'standard_custom_taxo',
1335
         ),
1336
        );
1337
    }
1338
1339
    /**
1340
     * @ticket 35614
1341
     */
1342
    public function test_taxonomy_capabilities_with_custom_caps_are_correct() 
1343
    {
1344
        $expected = array(
1345
         'manage_terms' => 'one',
1346
         'edit_terms'   => 'two',
1347
         'delete_terms' => 'three',
1348
         'assign_terms' => 'four',
1349
        );
1350
        $taxonomy = 'custom_cap_taxo';
1351
        register_taxonomy(
1352
            $taxonomy, 'post', array(
1353
            'capabilities' => $expected,
1354
            ) 
1355
        );
1356
1357
        $tax  = get_taxonomy($taxonomy);
1358
        $user = self::$users['administrator'];
1359
1360 View Code Duplication
        foreach ( $expected as $meta_cap => $primitive_cap ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1361
            $caps = map_meta_cap($tax->cap->$meta_cap, $user->ID);
1362
            $this->assertEquals(
1363
                array(
1364
                $primitive_cap,
1365
                ), $caps, "Meta cap: {$meta_cap}" 
1366
            );
1367
        }
1368
    }
1369
1370
    /**
1371
     * @ticket 21786
1372
     */
1373
    function test_negative_caps() 
1374
    {
1375
        $author = self::$users['author'];
1376
1377
        $author->add_cap('foo', false);
1378
        $this->assertTrue(isset($author->caps['foo']));
1379
        $this->assertFalse(user_can($author->ID, 'foo'));
1380
1381
        $author->remove_cap('foo');
1382
        $this->assertFalse(isset($author->caps['foo']));
1383
        $this->assertFalse(user_can($author->ID, 'foo'));
1384
    }
1385
1386
    /**
1387
     * @ticket 18932
1388
     */
1389
    function test_set_role_same_role() 
1390
    {
1391
        $user = self::$users['administrator'];
1392
        $caps = $user->caps;
1393
        $this->assertNotEmpty($user->caps);
1394
        $user->set_role('administrator');
1395
        $this->assertNotEmpty($user->caps);
1396
        $this->assertEquals($caps, $user->caps);
1397
    }
1398
1399
    function test_current_user_can_for_blog() 
1400
    {
1401
        global $wpdb;
1402
1403
        $user = self::$users['administrator'];
1404
        $old_uid = get_current_user_id();
1405
        wp_set_current_user($user->ID);
1406
1407
        $this->assertTrue(current_user_can_for_blog(get_current_blog_id(), 'edit_posts'));
1408
        $this->assertFalse(current_user_can_for_blog(get_current_blog_id(), 'foo_the_bar'));
1409
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1410
            $this->assertTrue(current_user_can_for_blog(12345, 'edit_posts'));
1411
            return;
1412
        }
1413
1414
        $suppress = $wpdb->suppress_errors();
1415
        $this->assertFalse(current_user_can_for_blog(12345, 'edit_posts'));
1416
        $wpdb->suppress_errors($suppress);
1417
1418
        $blog_id = self::factory()->blog->create(array( 'user_id' => $user->ID ));
1419
        $this->assertTrue(current_user_can_for_blog($blog_id, 'edit_posts'));
1420
        $this->assertFalse(current_user_can_for_blog($blog_id, 'foo_the_bar'));
1421
1422
        wp_set_current_user($old_uid);
1423
    }
1424
1425
    function test_borked_current_user_can_for_blog() 
1426
    {
1427
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1428
            $this->markTestSkipped('Test only runs in multisite');
1429
            return;
1430
        }
1431
1432
        $orig_blog_id = get_current_blog_id();
1433
        $blog_id = self::factory()->blog->create();
1434
1435
        $this->_nullify_current_user();
1436
1437
        add_action('switch_blog', array( $this, '_nullify_current_user_and_keep_nullifying_user' ));
1438
1439
        current_user_can_for_blog($blog_id, 'edit_posts');
1440
1441
        $this->assertEquals($orig_blog_id, get_current_blog_id());
1442
    }
1443
1444
    function _nullify_current_user() 
1445
    {
1446
        // Prevents fatal errors in ::tearDown()'s and other uses of restore_current_blog()
1447
        $function_stack = wp_debug_backtrace_summary(null, 0, false);
1448
        if (in_array('restore_current_blog', $function_stack) ) {
1449
            return;
1450
        }
1451
        $GLOBALS['current_user'] = null;
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1452
    }
1453
1454
    function _nullify_current_user_and_keep_nullifying_user() 
1455
    {
1456
        add_action('set_current_user', array( $this, '_nullify_current_user' ));
1457
    }
1458
1459
    /**
1460
     * @ticket 28374
1461
     */
1462
    function test_current_user_edit_caps() 
1463
    {
1464
        $user = new WP_User(self::factory()->user->create(array( 'role' => 'contributor' )));
1465
        wp_set_current_user($user->ID);
1466
1467
        $user->add_cap('publish_posts');
1468
        $user->add_cap('publish_pages');
1469
        $this->assertTrue($user->has_cap('publish_posts'));
1470
        $this->assertTrue($user->has_cap('publish_pages'));
1471
1472
        $user->remove_cap('publish_pages');
1473
        $this->assertFalse($user->has_cap('publish_pages'));
1474
    }
1475
1476
    function test_subscriber_cant_edit_posts() 
1477
    {
1478
        $user = self::$users['subscriber'];
1479
        wp_set_current_user($user->ID);
1480
1481
        $post = self::factory()->post->create(array( 'post_author' => 1 ));
1482
1483
        $this->assertFalse(current_user_can('edit_post', $post));
1484
        $this->assertFalse(current_user_can('edit_post', $post + 1));
1485
    }
1486
1487
    function test_multisite_administrator_can_not_edit_users() 
1488
    {
1489
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1490
            $this->markTestSkipped('Test only runs in multisite');
1491
            return;
1492
        }
1493
1494
        $user = self::$users['administrator'];
1495
        $other_user = self::$users['subscriber'];
1496
1497
        wp_set_current_user($user->ID);
1498
1499
        $this->assertFalse(current_user_can('edit_user', $other_user->ID));
1500
    }
1501
1502
    function test_user_can_edit_self() 
1503
    {
1504
        foreach ( self::$users as $role => $user ) {
1505
            wp_set_current_user($user->ID);
1506
            $this->assertTrue(current_user_can('edit_user', $user->ID), "User with role {$role} should have the capability to edit their own profile");
1507
        }
1508
    }
1509
1510 View Code Duplication
    public function test_only_admins_and_super_admins_can_remove_users() 
1511
    {
1512
        if (is_multisite() ) {
1513
            $this->assertTrue(user_can(self::$super_admin->ID,        'remove_user', self::$users['subscriber']->ID));
1514
        }
1515
1516
        $this->assertTrue(user_can(self::$users['administrator']->ID, 'remove_user', self::$users['subscriber']->ID));
1517
1518
        $this->assertFalse(user_can(self::$users['editor']->ID,       'remove_user', self::$users['subscriber']->ID));
1519
        $this->assertFalse(user_can(self::$users['author']->ID,       'remove_user', self::$users['subscriber']->ID));
1520
        $this->assertFalse(user_can(self::$users['contributor']->ID,  'remove_user', self::$users['subscriber']->ID));
1521
        $this->assertFalse(user_can(self::$users['subscriber']->ID,   'remove_user', self::$users['subscriber']->ID));
1522
    }
1523
1524 View Code Duplication
    public function test_only_super_admins_can_delete_users_on_multisite() 
1525
    {
1526
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1527
            $this->markTestSkipped('Test only runs on multisite');
1528
        }
1529
1530
        $this->assertTrue(user_can(self::$super_admin->ID,             'delete_user', self::$users['subscriber']->ID));
1531
1532
        $this->assertFalse(user_can(self::$users['administrator']->ID, 'delete_user', self::$users['subscriber']->ID));
1533
        $this->assertFalse(user_can(self::$users['editor']->ID,        'delete_user', self::$users['subscriber']->ID));
1534
        $this->assertFalse(user_can(self::$users['author']->ID,        'delete_user', self::$users['subscriber']->ID));
1535
        $this->assertFalse(user_can(self::$users['contributor']->ID,   'delete_user', self::$users['subscriber']->ID));
1536
        $this->assertFalse(user_can(self::$users['subscriber']->ID,    'delete_user', self::$users['subscriber']->ID));
1537
    }
1538
1539
    public function test_only_admins_can_delete_users_on_single_site() 
1540
    {
1541
        if (is_multisite() ) {
1542
            $this->markTestSkipped('Test does not run on multisite');
1543
        }
1544
1545
        $this->assertTrue(user_can(self::$users['administrator']->ID, 'delete_user', self::$users['subscriber']->ID));
1546
1547
        $this->assertFalse(user_can(self::$users['editor']->ID,       'delete_user', self::$users['subscriber']->ID));
1548
        $this->assertFalse(user_can(self::$users['author']->ID,       'delete_user', self::$users['subscriber']->ID));
1549
        $this->assertFalse(user_can(self::$users['contributor']->ID,  'delete_user', self::$users['subscriber']->ID));
1550
        $this->assertFalse(user_can(self::$users['subscriber']->ID,   'delete_user', self::$users['subscriber']->ID));
1551
    }
1552
1553 View Code Duplication
    public function test_only_admins_and_super_admins_can_promote_users() 
1554
    {
1555
        if (is_multisite() ) {
1556
            $this->assertTrue(user_can(self::$super_admin->ID,              'promote_user', self::$users['subscriber']->ID));
1557
        }
1558
1559
        $this->assertTrue(user_can(self::$users['administrator']->ID, 'promote_user', self::$users['subscriber']->ID));
1560
1561
        $this->assertFalse(user_can(self::$users['editor']->ID,       'promote_user', self::$users['subscriber']->ID));
1562
        $this->assertFalse(user_can(self::$users['author']->ID,       'promote_user', self::$users['subscriber']->ID));
1563
        $this->assertFalse(user_can(self::$users['contributor']->ID,  'promote_user', self::$users['subscriber']->ID));
1564
        $this->assertFalse(user_can(self::$users['subscriber']->ID,   'promote_user', self::$users['subscriber']->ID));
1565
    }
1566
1567
    /**
1568
     * @ticket 33694
1569
     */
1570
    function test_contributor_cannot_edit_scheduled_post() 
1571
    {
1572
1573
        // Add a contributor
1574
        $contributor = self::$users['contributor'];
1575
1576
        // Give them a scheduled post
1577
        $post = $this->factory->post->create_and_get(
1578
            array(
1579
            'post_author' => $contributor->ID,
1580
            'post_status' => 'future',
1581
            ) 
1582
        );
1583
1584
        // Ensure contributor can't edit or trash the post
1585
        $this->assertFalse(user_can($contributor->ID, 'edit_post', $post->ID));
1586
        $this->assertFalse(user_can($contributor->ID, 'delete_post', $post->ID));
1587
1588
        // Test the tests
1589
        $this->assertTrue(defined('EMPTY_TRASH_DAYS'));
1590
        $this->assertNotEmpty(EMPTY_TRASH_DAYS);
1591
1592
        // Trash it
1593
        $trashed = wp_trash_post($post->ID);
1594
        $this->assertNotEmpty($trashed);
1595
1596
        // Ensure contributor can't edit, un-trash, or delete the post
1597
        $this->assertFalse(user_can($contributor->ID, 'edit_post', $post->ID));
1598
        $this->assertFalse(user_can($contributor->ID, 'delete_post', $post->ID));
1599
1600
    }
1601
1602 View Code Duplication
    function test_multisite_administrator_with_manage_network_users_can_edit_users() 
1603
    {
1604
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1605
            $this->markTestSkipped('Test only runs in multisite');
1606
            return;
1607
        }
1608
1609
        $user = self::$users['administrator'];
1610
        $user->add_cap('manage_network_users');
1611
        $other_user = self::$users['subscriber'];
1612
1613
        wp_set_current_user($user->ID);
1614
1615
        $can_edit_user = current_user_can('edit_user', $other_user->ID);
1616
1617
        $user->remove_cap('manage_network_users');
1618
1619
        $this->assertTrue($can_edit_user);
1620
    }
1621
1622 View Code Duplication
    function test_multisite_administrator_with_manage_network_users_can_not_edit_super_admin() 
1623
    {
1624
        if (! is_multisite() ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
1625
            $this->markTestSkipped('Test only runs in multisite');
1626
            return;
1627
        }
1628
1629
        $user = self::$users['administrator'];
1630
        $user->add_cap('manage_network_users');
1631
1632
        wp_set_current_user($user->ID);
1633
1634
        $can_edit_user = current_user_can('edit_user', self::$super_admin->ID);
1635
1636
        $user->remove_cap('manage_network_users');
1637
1638
        $this->assertFalse($can_edit_user);
1639
    }
1640
1641
    /**
1642
     * @ticket 16956
1643
     */
1644
    function test_require_edit_others_posts_if_post_type_doesnt_exist() 
1645
    {
1646
        register_post_type('existed');
1647
        $post_id = self::factory()->post->create(array( 'post_type' => 'existed' ));
1648
        _unregister_post_type('existed');
1649
1650
        $subscriber_id = self::$users['subscriber']->ID;
1651
        $editor_id = self::$users['editor']->ID;
1652
1653
        $this->setExpectedIncorrectUsage('map_meta_cap');
1654
        foreach ( array( 'delete_post', 'edit_post', 'read_post', 'publish_post' ) as $cap ) {
1655
            wp_set_current_user($subscriber_id);
1656
            $this->assertSame(array( 'edit_others_posts' ), map_meta_cap($cap, $subscriber_id, $post_id));
1657
            $this->assertFalse(current_user_can($cap, $post_id));
1658
1659
            wp_set_current_user($editor_id);
1660
            $this->assertSame(array( 'edit_others_posts' ), map_meta_cap($cap, $editor_id, $post_id));
1661
            $this->assertTrue(current_user_can($cap, $post_id));
1662
        }
1663
    }
1664
1665
    /**
1666
     * @ticket 17253
1667
     */
1668
    function test_cpt_with_page_capability_type() 
1669
    {
1670
1671
        register_post_type(
1672
            'page_capability', array(
1673
            'capability_type' => 'page',
1674
            ) 
1675
        );
1676
1677
        $cpt = get_post_type_object('page_capability');
1678
1679
        $admin       = self::$users['administrator'];
1680
        $editor      = self::$users['editor'];
1681
        $author      = self::$users['author'];
1682
        $contributor = self::$users['contributor'];
1683
1684
        $this->assertEquals('edit_pages', $cpt->cap->edit_posts);
1685
        $this->assertTrue(user_can($admin->ID, $cpt->cap->edit_posts));
1686
        $this->assertTrue(user_can($editor->ID, $cpt->cap->edit_posts));
1687
        $this->assertFalse(user_can($author->ID, $cpt->cap->edit_posts));
1688
        $this->assertFalse(user_can($contributor->ID, $cpt->cap->edit_posts));
1689
1690
        $admin_post = self::factory()->post->create_and_get(
1691
            array(
1692
            'post_author' => $admin->ID,
1693
            'post_type'   => 'page_capability',
1694
            ) 
1695
        );
1696
1697
        $this->assertTrue(user_can($admin->ID, 'edit_post', $admin_post->ID));
1698
        $this->assertTrue(user_can($editor->ID, 'edit_post', $admin_post->ID));
1699
        $this->assertFalse(user_can($author->ID, 'edit_post', $admin_post->ID));
1700
        $this->assertFalse(user_can($contributor->ID, 'edit_post', $admin_post->ID));
1701
1702
        $author_post = self::factory()->post->create_and_get(
1703
            array(
1704
            'post_author' => $author->ID,
1705
            'post_type'   => 'page_capability',
1706
            ) 
1707
        );
1708
1709
        $this->assertTrue(user_can($admin->ID, 'edit_post', $author_post->ID));
1710
        $this->assertTrue(user_can($editor->ID, 'edit_post', $author_post->ID));
1711
        $this->assertFalse(user_can($author->ID, 'edit_post', $author_post->ID));
1712
        $this->assertFalse(user_can($contributor->ID, 'edit_post', $author_post->ID));
1713
1714
        _unregister_post_type('page_capability');
1715
1716
    }
1717
1718
    public function testNonLoggedInUsersHaveNoCapabilities() 
0 ignored issues
show
Coding Style introduced by
The function name testNonLoggedInUsersHaveNoCapabilities is in camel caps, but expected test_non_logged_in_users_have_no_capabilities instead as per the coding standard.
Loading history...
1719
    {
1720
1721
        $this->assertFalse(is_user_logged_in());
1722
1723
        $caps = $this->getAllCapsAndRoles();
1724
1725
        foreach ( $caps as $cap => $roles ) {
1726
            $this->assertFalse(current_user_can($cap), "Non-logged-in user should not have the {$cap} capability");
1727
        }
1728
1729
        $this->assertFalse(current_user_can('start_a_fire'), "Non-logged-in user should not have a custom capability");
1730
        $this->assertFalse(current_user_can('do_not_allow'), "Non-logged-in user should not have the do_not_allow capability");
1731
    }
1732
1733
    protected $_role_test_wp_roles_role;
1734
    /**
1735
     * @ticket 23016
1736
     */
1737
    public function test_wp_roles_init_action() 
1738
    {
1739
        $this->_role_test_wp_roles_init = array(
1740
         'role' => 'test_wp_roles_init',
1741
         'info' => array(
1742
          'name' => 'Test WP Roles Init',
1743
          'capabilities' => array( 'testing_magic' => true ),
1744
         ),
1745
        );
1746
        add_action('wp_roles_init', array( $this, '_hook_wp_roles_init' ), 10, 1);
1747
1748
        $wp_roles = new WP_Roles();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1749
1750
        remove_action('wp_roles_init', array( $this, '_hook_wp_roles_init' ));
1751
1752
        $expected = new WP_Role($this->_role_test_wp_roles_init['role'], $this->_role_test_wp_roles_init['info']['capabilities']);
1753
1754
        $role = $wp_roles->get_role($this->_role_test_wp_roles_init['role']);
1755
1756
        $this->assertEquals($expected, $role);
1757
        $this->assertContains($this->_role_test_wp_roles_init['info']['name'], $wp_roles->role_names);
1758
    }
1759
1760
    public function _hook_wp_roles_init( $wp_roles ) 
1761
    {
1762
        $wp_roles->add_role($this->_role_test_wp_roles_init['role'], $this->_role_test_wp_roles_init['info']['name'], $this->_role_test_wp_roles_init['info']['capabilities']);
1763
    }
1764
1765
    /**
1766
     * @ticket 23016
1767
     * @expectedDeprecated WP_Roles::reinit
1768
     */
1769
    public function test_wp_roles_reinit_deprecated() 
1770
    {
1771
        $wp_roles = new WP_Roles();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1772
        $wp_roles->reinit();
1773
    }
1774
1775
    /**
1776
     * @ticket 38412
1777
     */
1778
    public function test_no_one_can_edit_user_meta_for_non_existent_term() 
1779
    {
1780
        wp_set_current_user(self::$super_admin->ID);
1781
        $this->assertFalse(current_user_can('edit_user_meta', 999999));
1782
    }
1783
1784
    /**
1785
     * @ticket 38412
1786
     */
1787 View Code Duplication
    public function test_user_can_edit_user_meta() 
1788
    {
1789
        wp_set_current_user(self::$users['administrator']->ID);
1790
        if (is_multisite() ) {
1791
            grant_super_admin(self::$users['administrator']->ID);
1792
        }
1793
        $this->assertTrue(current_user_can('edit_user_meta', self::$users['subscriber']->ID, 'foo'));
1794
    }
1795
1796
    /**
1797
     * @ticket 38412
1798
     */
1799
    public function test_user_cannot_edit_user_meta() 
1800
    {
1801
        wp_set_current_user(self::$users['editor']->ID);
1802
        $this->assertFalse(current_user_can('edit_user_meta', self::$users['subscriber']->ID, 'foo'));
1803
    }
1804
1805
    /**
1806
     * @ticket 38412
1807
     */
1808
    public function test_no_one_can_delete_user_meta_for_non_existent_term() 
1809
    {
1810
        wp_set_current_user(self::$super_admin->ID);
1811
        $this->assertFalse(current_user_can('delete_user_meta', 999999, 'foo'));
1812
    }
1813
1814
    /**
1815
     * @ticket 38412
1816
     */
1817 View Code Duplication
    public function test_user_can_delete_user_meta() 
1818
    {
1819
        wp_set_current_user(self::$users['administrator']->ID);
1820
        if (is_multisite() ) {
1821
            grant_super_admin(self::$users['administrator']->ID);
1822
        }
1823
        $this->assertTrue(current_user_can('delete_user_meta', self::$users['subscriber']->ID, 'foo'));
1824
    }
1825
1826
    /**
1827
     * @ticket 38412
1828
     */
1829
    public function test_user_cannot_delete_user_meta() 
1830
    {
1831
        wp_set_current_user(self::$users['editor']->ID);
1832
        $this->assertFalse(current_user_can('delete_user_meta', self::$users['subscriber']->ID, 'foo'));
1833
    }
1834
1835
    /**
1836
     * @ticket 38412
1837
     */
1838
    public function test_no_one_can_add_user_meta_for_non_existent_term() 
1839
    {
1840
        wp_set_current_user(self::$super_admin->ID);
1841
        $this->assertFalse(current_user_can('add_user_meta', 999999, 'foo'));
1842
    }
1843
1844
    /**
1845
     * @ticket 38412
1846
     */
1847 View Code Duplication
    public function test_user_can_add_user_meta() 
1848
    {
1849
        wp_set_current_user(self::$users['administrator']->ID);
1850
        if (is_multisite() ) {
1851
            grant_super_admin(self::$users['administrator']->ID);
1852
        }
1853
        $this->assertTrue(current_user_can('add_user_meta', self::$users['subscriber']->ID, 'foo'));
1854
    }
1855
1856
    /**
1857
     * @ticket 38412
1858
     */
1859
    public function test_user_cannot_add_user_meta() 
1860
    {
1861
        wp_set_current_user(self::$users['editor']->ID);
1862
        $this->assertFalse(current_user_can('add_user_meta', self::$users['subscriber']->ID, 'foo'));
1863
    }
1864
}
1865