Completed
Push — feature/reorg ( 2e8e86...35db6f )
by
unknown
25:00 queued 15:50
created

Test_Admin_Menu::test_add_plugins_menu()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 34
rs 9.376
c 0
b 0
f 0
1
<?php
2
/**
3
 * Tests for Admin_Menu class.
4
 *
5
 * @package Jetpack
6
 */
7
8
use Automattic\Jetpack\Dashboard_Customizations\Admin_Menu;
9
use Automattic\Jetpack\Status;
10
11
require_jetpack_file( 'modules/masterbar/admin-menu/class-admin-menu.php' );
12
require_jetpack_file( 'tests/php/modules/masterbar/data/admin-menu.php' );
13
14
/**
15
 * Class Test_Admin_Menu
16
 *
17
 * @coversDefaultClass Automattic\Jetpack\Dashboard_Customizations\Admin_Menu
18
 */
19
class Test_Admin_Menu extends WP_UnitTestCase {
20
21
	/**
22
	 * Menu data fixture.
23
	 *
24
	 * @var array
25
	 */
26
	public static $menu_data;
27
28
	/**
29
	 * Submenu data fixture.
30
	 *
31
	 * @var array
32
	 */
33
	public static $submenu_data;
34
35
	/**
36
	 * Test domain.
37
	 *
38
	 * @var string
39
	 */
40
	public static $domain;
41
42
	/**
43
	 * Admin menu instance.
44
	 *
45
	 * @var Admin_Menu
46
	 */
47
	public static $admin_menu;
48
49
	/**
50
	 * Mock user ID.
51
	 *
52
	 * @var int
53
	 */
54
	private static $user_id = 0;
55
56
	/**
57
	 * Create shared fixtures.
58
	 *
59
	 * @param WP_UnitTest_Factory $factory Fixture factory.
60
	 */
61 View Code Duplication
	public static function wpSetUpBeforeClass( $factory ) {
62
		static::$domain  = ( new Status() )->get_site_suffix();
63
		static::$user_id = $factory->user->create( array( 'role' => 'administrator' ) );
0 ignored issues
show
Bug introduced by
Since $user_id is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $user_id to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
64
65
		static::$menu_data    = get_menu_fixture();
66
		static::$submenu_data = get_submenu_fixture();
67
	}
68
69
	/**
70
	 * Set up data.
71
	 */
72 View Code Duplication
	public function setUp() {
73
		parent::setUp();
74
		global $menu, $submenu;
75
76
		// Initialize in setUp so it registers hooks for every test.
77
		static::$admin_menu = Admin_Menu::get_instance();
78
79
		$menu    = static::$menu_data;
80
		$submenu = static::$submenu_data;
81
82
		wp_set_current_user( static::$user_id );
0 ignored issues
show
Bug introduced by
Since $user_id is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $user_id to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
83
	}
84
85
	/**
86
	 * Test get_instance.
87
	 *
88
	 * @covers ::get_instance
89
	 * @covers ::__construct
90
	 */
91 View Code Duplication
	public function test_get_instance() {
92
		$instance = Admin_Menu::get_instance();
93
94
		$this->assertInstanceOf( Admin_Menu::class, $instance );
95
		$this->assertSame( $instance, static::$admin_menu );
96
97
		$this->assertSame( 99999, has_action( 'admin_menu', array( $instance, 'reregister_menu_items' ) ) );
98
		$this->assertSame( 10, has_action( 'admin_enqueue_scripts', array( $instance, 'enqueue_scripts' ) ) );
99
	}
100
101
	/**
102
	 * Tests add_admin_menu_separator
103
	 *
104
	 * @covers ::add_admin_menu_separator
105
	 */
106
	public function test_add_admin_menu_separator() {
107
		global $menu;
108
109
		// Start with a clean slate.
110
		$temp_menu = $menu;
111
		$menu      = array();
112
113
		static::$admin_menu->add_admin_menu_separator( 15 );
114
		static::$admin_menu->add_admin_menu_separator( 10, 'manage_options' );
115
116
		$this->assertSame( array( 10, 15 ), array_keys( $menu ), 'Menu should be ordered by position parameter.' );
117
		$this->assertSame( 'manage_options', $menu[10][1] );
118
		$this->assertSame( 'separator-custom-5', $menu[10][2] );
119
		$this->assertSame( 'read', $menu[15][1] );
120
		$this->assertSame( 'separator-custom-4', $menu[15][2] );
121
122
		// Restore filtered $menu.
123
		$menu = $temp_menu;
124
	}
125
126
	/**
127
	 * Test_Admin_Menu.
128
	 *
129
	 * @covers ::reregister_menu_items
130
	 */
131
	public function test_admin_menu_output() {
132
		global $menu, $submenu;
133
134
		static::$admin_menu->reregister_menu_items();
135
136
		$this->assertSame(
137
			array_keys( $menu ),
138
			array( 2, 3, '3.86682', 4, 5, 10, 15, 20, 25, 59, 60, 65, 70, 75, 80 ),
139
			'Admin menu should not have unexpected top menu items.'
140
		);
141
142
		$this->assertEquals( static::$menu_data[80], $menu[80], 'Settings menu should stay the same.' );
143
		$this->assertEquals( static::$submenu_data[''], $submenu[''], 'Submenu items without parent should stay the same.' );
144
	}
145
146
	/**
147
	 * Shim wpcomsh fallback site icon.
148
	 *
149
	 * @return string
150
	 */
151
	public function wpcomsh_site_icon_url() {
152
		return 'https://s0.wp.com/i/webclip.png';
153
	}
154
155
	/**
156
	 * Custom site icon.
157
	 *
158
	 * @return string
159
	 */
160
	public function custom_site_icon_url() {
161
		return 'https://s0.wp.com/i/jetpack.png';
162
	}
163
164
	/**
165
	 * Tests add_my_home_menu
166
	 *
167
	 * @covers ::add_my_home_menu
168
	 */
169
	public function test_add_my_home_menu() {
170
		global $menu, $submenu;
171
172
		static::$admin_menu->add_my_home_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
173
174
		$slug = 'https://wordpress.com/home/' . static::$domain;
175
176
		$my_home_menu_item = array(
177
			'My Home',
178
			'read',
179
			$slug,
180
			'My Home',
181
			'menu-top toplevel_page_' . $slug,
182
			'toplevel_page_' . $slug,
183
			'dashicons-admin-home',
184
		);
185
		$this->assertSame( $menu[2], $my_home_menu_item );
186
187
		// Has My Home submenu item when there are other submenu items.
188
		$my_home_submenu_item = array(
189
			'My Home',
190
			'read',
191
			$slug,
192
			'My Home',
193
		);
194
		$this->assertContains( $my_home_submenu_item, $submenu[ $slug ] );
195
		// Reset data.
196
		$menu    = static::$menu_data;
197
		$submenu = static::$submenu_data;
198
199
		// Has no ny Home submenu when there are no other submenus.
200
		$submenu['index.php'] = array(
201
			0 => array( 'Home', 'read', 'index.php' ),
202
		);
203
204
		static::$admin_menu->add_my_home_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
205
206
		$this->assertArrayNotHasKey( 'https://wordpress.com/home/' . static::$domain, $submenu );
207
	}
208
209
	/**
210
	 * Tests add_stats_menu
211
	 *
212
	 * @covers ::add_stats_menu
213
	 */
214
	public function test_add_stats_menu() {
215
		global $menu, $submenu;
216
217
		static::$admin_menu->add_stats_menu( static::$domain );
0 ignored issues
show
Unused Code introduced by
The call to Admin_Menu::add_stats_menu() has too many arguments starting with static::$domain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
218
219
		$menu_title = __( 'Stats', 'jetpack' );
220
221
		if ( ! defined( 'TESTING_IN_JETPACK' ) || ! TESTING_IN_JETPACK ) {
222
			$menu_title .= sprintf(
223
				'<img class="sidebar-unified__sparkline" width="80" height="20" src="%1$s" alt="%2$s">',
224
				esc_url( home_url( 'wp-includes/charts/admin-bar-hours-scale-2x.php?masterbar=1&s=' . get_current_blog_id() ) ),
225
				esc_attr__( 'Hourly views', 'jetpack' )
226
			);
227
		}
228
		$stats_menu_item = array(
229
			$menu_title,
230
			'edit_posts',
231
			'https://wordpress.com/stats/day/' . static::$domain,
232
			'Stats',
233
			'menu-top toplevel_page_https://wordpress.com/stats/day/' . static::$domain,
234
			'toplevel_page_https://wordpress.com/stats/day/' . static::$domain,
235
			'dashicons-chart-bar',
236
		);
237
238
		$this->assertSame( $menu['3.86682'], $stats_menu_item );
239
		$this->assertArrayNotHasKey( 'https://wordpress.com/stats/day/' . static::$domain, $submenu );
240
	}
241
242
	/**
243
	 * Tests add_upgrades_menu
244
	 *
245
	 * @covers ::add_upgrades_menu
246
	 */
247
	public function test_add_wpcom_upgrades_menu() {
248
		global $menu, $submenu;
249
250
		static::$admin_menu->add_upgrades_menu();
251
252
		$slug = 'https://wordpress.com/plans/' . static::$domain;
253
254
		$upgrades_menu_item = array(
255
			'Upgrades',
256
			'manage_options',
257
			$slug,
258
			'Upgrades',
259
			'menu-top toplevel_page_https://wordpress.com/plans/' . static::$domain,
260
			'toplevel_page_https://wordpress.com/plans/' . static::$domain,
261
			'dashicons-cart',
262
		);
263
		$this->assertSame( $menu['4.80608'], $upgrades_menu_item );
264
265
		$plans_submenu_item = array(
266
			'Plans',
267
			'manage_options',
268
			$slug,
269
			'Plans',
270
		);
271
		$this->assertContains( $plans_submenu_item, $submenu[ $slug ] );
272
273
		$purchases_submenu_item = array(
274
			'Purchases',
275
			'manage_options',
276
			'https://wordpress.com/purchases/subscriptions/' . static::$domain,
277
			'Purchases',
278
		);
279
		$this->assertContains( $purchases_submenu_item, $submenu[ $slug ] );
280
	}
281
282
	/**
283
	 * Tests add_jetpack_upgrades_menu
284
	 *
285
	 * @covers ::add_jetpack_upgrades_menu
286
	 */
287 View Code Duplication
	public function test_add_jetpack_upgrades_menu() {
288
		global $menu, $submenu;
289
290
		static::$admin_menu->add_upgrades_menu( static::$domain );
0 ignored issues
show
Unused Code introduced by
The call to Admin_Menu::add_upgrades_menu() has too many arguments starting with static::$domain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
291
292
		$slug = 'https://wordpress.com/plans/' . static::$domain;
293
294
		$upgrades_menu_item = array(
295
			'Upgrades',
296
			'manage_options',
297
			$slug,
298
			'Upgrades',
299
			'menu-top toplevel_page_https://wordpress.com/plans/' . static::$domain,
300
			'toplevel_page_https://wordpress.com/plans/' . static::$domain,
301
			'dashicons-cart',
302
		);
303
		$this->assertSame( $menu['4.80608'], $upgrades_menu_item );
304
		$this->assertArrayNotHasKey( 'https://wordpress.com/domains/manage/' . static::$domain, $submenu );
305
	}
306
307
	/**
308
	 * Tests add_posts_menu
309
	 *
310
	 * @covers ::add_posts_menu
311
	 */
312 View Code Duplication
	public function test_add_posts_menu() {
313
		global $menu, $submenu;
314
315
		static::$admin_menu->add_posts_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
316
317
		$posts_menu_item = array(
318
			'Posts',
319
			'edit_posts',
320
			'https://wordpress.com/posts/' . static::$domain,
321
			'Posts',
322
			'menu-top toplevel_page_https://wordpress.com/posts/' . static::$domain,
323
			'toplevel_page_https://wordpress.com/posts/' . static::$domain,
324
			'dashicons-admin-post',
325
		);
326
327
		$this->assertSame( $menu[5], $posts_menu_item );
328
		$this->assertArrayNotHasKey( 'edit.php', $submenu );
329
	}
330
331
	/**
332
	 * Tests add_media_menu
333
	 *
334
	 * @covers ::add_media_menu
335
	 */
336
	public function test_add_media_menu() {
337
		global $menu, $submenu;
338
339
		static::$admin_menu->add_media_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
340
341
		$slug = 'https://wordpress.com/media/' . static::$domain;
342
343
		$media_menu_item = array(
344
			'Media',
345
			'upload_files',
346
			$slug,
347
			'Media',
348
			'menu-top toplevel_page_' . $slug,
349
			'toplevel_page_' . $slug,
350
			'dashicons-admin-media',
351
		);
352
353
		$this->assertSame( $menu[10], $media_menu_item );
354
		$this->assertArrayNotHasKey( $slug, $submenu );
355
356
		$library_submenu_item = array(
357
			'Library',
358
			'upload_files',
359
			'upload.php',
360
		);
361
		$this->assertNotContains( $library_submenu_item, $submenu['upload.php'] );
362
363
		$add_new_submenu_item = array(
364
			'Add New',
365
			'upload_files',
366
			'media-new.php',
367
		);
368
		$this->assertNotContains( $add_new_submenu_item, $submenu['upload.php'] );
369
	}
370
371
	/**
372
	 * Tests add_page_menu
373
	 *
374
	 * @covers ::add_page_menu
375
	 */
376 View Code Duplication
	public function test_add_page_menu() {
377
		global $menu, $submenu;
378
379
		static::$admin_menu->add_page_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
380
381
		$posts_menu_item = array(
382
			'Pages',
383
			'edit_pages',
384
			'https://wordpress.com/pages/' . static::$domain,
385
			'Pages',
386
			'menu-top toplevel_page_https://wordpress.com/pages/' . static::$domain,
387
			'toplevel_page_https://wordpress.com/pages/' . static::$domain,
388
			'dashicons-admin-page',
389
		);
390
391
		$this->assertSame( $menu[20], $posts_menu_item );
392
		$this->assertEmpty( $submenu['edit.php?post_type=page'] );
393
	}
394
395
	/**
396
	 * Tests add_comments_menu
397
	 *
398
	 * @covers ::add_comments_menu
399
	 */
400
	public function test_add_comments_menu() {
401
		global $menu, $submenu;
402
403
		// Only users that can edit posts get to see the comments menu.
404
		wp_set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
405
		$menu = array();
406
		static::$admin_menu->add_comments_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
407
		$this->assertEmpty( $menu );
408
409
		// Reset.
410
		wp_set_current_user( static::$user_id );
0 ignored issues
show
Bug introduced by
Since $user_id is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $user_id to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
411
		$menu = static::$menu_data;
412
413
		static::$admin_menu->add_comments_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
414
415
		$comments_menu_item = array(
416
			'Comments <span class="awaiting-mod count-0"><span class="pending-count" aria-hidden="true">0</span><span class="comments-in-moderation-text screen-reader-text">0 Comments in moderation</span></span>',
417
			'edit_posts',
418
			'https://wordpress.com/comments/all/' . static::$domain,
419
			'Comments',
420
			'menu-top toplevel_page_https://wordpress.com/comments/all/' . static::$domain,
421
			'toplevel_page_https://wordpress.com/comments/all/' . static::$domain,
422
			'dashicons-admin-comments',
423
		);
424
425
		$this->assertSame( $menu[25], $comments_menu_item );
426
		$this->assertEmpty( $submenu['edit-comments.php'] );
427
	}
428
429
	/**
430
	 * Tests add_appearance_menu
431
	 *
432
	 * @covers ::add_appearance_menu
433
	 */
434
	public function test_add_appearance_menu() {
435
		global $menu, $submenu;
436
437
		static::$admin_menu->add_appearance_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
438
439
		$slug = 'https://wordpress.com/customize/' . static::$domain;
440
441
		$appearance_menu_item = array(
442
			'Appearance',
443
			'customize',
444
			$slug,
445
			'Appearance',
446
			'menu-top toplevel_page_' . $slug,
447
			'toplevel_page_' . $slug,
448
			'dashicons-admin-appearance',
449
		);
450
451
		$this->assertSame( $menu[60], $appearance_menu_item );
452
		$this->assertArrayNotHasKey( 'themes.php', $submenu );
453
454
		$customize_submenu_item = array(
455
			'Customize',
456
			'customize',
457
			'https://wordpress.com/customize/' . static::$domain,
458
			'Customize',
459
		);
460
		$this->assertContains( $customize_submenu_item, $submenu[ $slug ] );
461
462
		$themes_submenu_item = array(
463
			'Themes',
464
			'switch_themes',
465
			'https://wordpress.com/themes/' . static::$domain,
466
			'Themes',
467
		);
468
		$this->assertContains( $themes_submenu_item, $submenu[ $slug ] );
469
470
		$widgets_submenu_item = array(
471
			'Widgets',
472
			'customize',
473
			'https://wordpress.com/customize/' . static::$domain . '?autofocus%5Bpanel%5D=widgets',
474
			'Widgets',
475
		);
476
		$this->assertContains( $widgets_submenu_item, $submenu[ $slug ] );
477
478
		$menus_submenu_item = array(
479
			'Menus',
480
			'customize',
481
			'https://wordpress.com/customize/' . static::$domain . '?autofocus%5Bpanel%5D=nav_menus',
482
			'Menus',
483
		);
484
		$this->assertContains( $menus_submenu_item, $submenu[ $slug ] );
485
	}
486
487
	/**
488
	 * Tests add_users_menu
489
	 *
490
	 * @covers ::add_users_menu
491
	 */
492 View Code Duplication
	public function test_add_users_menu() {
493
		global $menu, $submenu;
494
495
		// Current user can't list users.
496
		wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) );
497
		$menu = array();
498
499
		static::$admin_menu->add_users_menu( true );
500
501
		$this->assertEmpty( $menu );
502
503
		// Reset.
504
		wp_set_current_user( static::$user_id );
0 ignored issues
show
Bug introduced by
Since $user_id is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $user_id to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
505
		$menu = static::$menu_data;
506
507
		static::$admin_menu->add_users_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
508
509
		$slug = 'https://wordpress.com/people/team/' . static::$domain;
510
511
		$users_menu_item = array(
512
			'Users',
513
			'list_users',
514
			$slug,
515
			'Users',
516
			'menu-top toplevel_page_' . $slug,
517
			'toplevel_page_' . $slug,
518
			'dashicons-admin-users',
519
		);
520
		$this->assertSame( $menu[70], $users_menu_item );
521
		$this->assertEmpty( $submenu['users.php'] );
522
523
		$all_people_submenu_item = array(
524
			'All People',
525
			'list_users',
526
			$slug,
527
			'All People',
528
		);
529
		$this->assertContains( $all_people_submenu_item, $submenu[ $slug ] );
530
531
		$add_new_submenu_item = array(
532
			'Add New',
533
			'promote_users',
534
			'https://wordpress.com/people/new/' . static::$domain,
535
			'Add New',
536
		);
537
		$this->assertContains( $add_new_submenu_item, $submenu[ $slug ] );
538
539
		$profile_submenu_item = array(
540
			'My Profile',
541
			'read',
542
			'https://wordpress.com/me',
543
			'My Profile',
544
		);
545
		$this->assertContains( $profile_submenu_item, $submenu[ $slug ] );
546
547
		$account_submenu_item = array(
548
			'Account Settings',
549
			'read',
550
			'https://wordpress.com/me/account',
551
			'Account Settings',
552
		);
553
		$this->assertContains( $account_submenu_item, $submenu[ $slug ] );
554
	}
555
556
	/**
557
	 * Tests add_tools_menu
558
	 *
559
	 * @covers ::add_tools_menu
560
	 */
561
	public function test_add_tools_menu() {
562
		global $menu, $submenu;
563
564
		$slug = 'https://wordpress.com/marketing/tools/' . static::$domain;
565
		static::$admin_menu->add_tools_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
566
567
		$tools_menu_item = array(
568
			'Tools',
569
			'manage_options',
570
			$slug,
571
			'Tools',
572
			'menu-top toplevel_page_' . $slug,
573
			'toplevel_page_' . $slug,
574
			'dashicons-admin-tools',
575
		);
576
577
		$this->assertSame( $menu[75], $tools_menu_item );
578
		$this->assertArrayNotHasKey( 'tools.php', $submenu );
579
580
		// Contains the following menu items.
581
582
		$import_submenu_item = array(
583
			'Import',
584
			'import',
585
			'https://wordpress.com/import/' . static::$domain,
586
			'Import',
587
		);
588
		$this->assertContains( $import_submenu_item, $submenu[ $slug ] );
589
590
		$export_submenu_item = array(
591
			'Export',
592
			'export',
593
			'https://wordpress.com/export/' . static::$domain,
594
			'Export',
595
		);
596
		$this->assertContains( $export_submenu_item, $submenu[ $slug ] );
597
598
		// NOT contains the following menu items.
599
600
		$tools_submenu_item = array(
601
			'Available Tools',
602
			'edit_posts',
603
			'tools.php',
604
		);
605
		$this->assertNotContains( $tools_submenu_item, $submenu[ $slug ] );
606
607
		$import_submenu_item = array(
608
			'Import',
609
			'import',
610
			'import.php',
611
		);
612
		$this->assertNotContains( $import_submenu_item, $submenu[ $slug ] );
613
614
		$export_submenu_item = array(
615
			'Export',
616
			'export',
617
			'export.php',
618
		);
619
		$this->assertNotContains( $export_submenu_item, $submenu[ $slug ] );
620
	}
621
622
	/**
623
	 * Tests add_options_menu
624
	 *
625
	 * @covers ::add_options_menu
626
	 */
627
	public function test_add_options_menu() {
628
		global $submenu;
629
630
		static::$admin_menu->add_options_menu( static::$domain );
0 ignored issues
show
Documentation introduced by
static::$domain is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
631
632
		$this->assertNotContains( 'options-discussion.php', $submenu['options-general.php'] );
633
		$this->assertNotContains( 'options-writing.php', $submenu['options-general.php'] );
634
	}
635
636
	/**
637
	 * Tests migrate_submenus
638
	 *
639
	 * @covers ::migrate_submenus
640
	 */
641
	public function test_migrate_submenus() {
642
		global $submenu;
643
644
		$new_slug = 'made-up-slug';
645
646
		// Start with a clean slate.
647
		$temp_submenu = $submenu;
648
		$submenu      = static::$submenu_data;
649
650
		// New slug doesn't exist yet.
651
		static::$admin_menu->migrate_submenus( 'edit.php', $new_slug );
652
		$this->assertArrayNotHasKey( 'edit.php', $submenu );
653
		$this->assertSame( static::$submenu_data['edit.php'], $submenu[ $new_slug ] );
654
655
		// New slug exists.
656
		static::$admin_menu->migrate_submenus( 'upload.php', $new_slug );
657
		$this->assertArrayNotHasKey( 'upload.php', $submenu );
658
		$expected = array_replace( static::$submenu_data['edit.php'], static::$submenu_data['upload.php'] );
659
		$this->assertSame( $expected, $submenu[ $new_slug ] );
660
661
		// Old slug doesn't exist.
662
		$this->assertArrayNotHasKey( 'unkown', $submenu );
663
		$pre_migration = $submenu;
664
		static::$admin_menu->migrate_submenus( 'unkown', $new_slug );
665
		$this->assertSame( $pre_migration, $submenu );
666
667
		// Slugs are the same.
668
		$this->assertArrayHasKey( 'index.php', $submenu );
669
		$pre_migration = $submenu;
670
		static::$admin_menu->migrate_submenus( 'index.php', 'index.php' );
671
		$this->assertSame( $pre_migration, $submenu );
672
673
		// Restore filtered $submenu.
674
		$submenu = $temp_submenu;
675
	}
676
}
677