Completed
Push — feature/reorg ( 6b724c...2e8e86 )
by
unknown
09:57 queued 10s
created

Test_Admin_Menu::test_add_new_site_link()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 16
rs 9.7333
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
10
require_jetpack_file( 'modules/masterbar/admin-menu/class-admin-menu.php' );
11
12
/**
13
 * Class Test_Admin_Menu
14
 *
15
 * @coversDefaultClass Automattic\Jetpack\Dashboard_Customizations\Admin_Menu
16
 */
17
class Test_Admin_Menu extends WP_UnitTestCase {
18
19
	/**
20
	 * Menu data fixture.
21
	 *
22
	 * @var array
23
	 */
24
	public static $menu_data;
25
26
	/**
27
	 * Submenu data fixture.
28
	 *
29
	 * @var array
30
	 */
31
	public static $submenu_data;
32
33
	/**
34
	 * Test domain.
35
	 *
36
	 * @var string
37
	 */
38
	public static $domain;
39
40
	/**
41
	 * Admin menu instance.
42
	 *
43
	 * @var Admin_Menu
44
	 */
45
	public static $admin_menu;
46
47
	/**
48
	 * Mock user ID.
49
	 *
50
	 * @var int
51
	 */
52
	private static $user_id = 0;
53
54
	/**
55
	 * Create shared fixtures.
56
	 *
57
	 * @param WP_UnitTest_Factory $factory Fixture factory.
58
	 */
59
	public static function wpSetUpBeforeClass( $factory ) {
60
		global $menu, $submenu;
61
62
		require_jetpack_file( 'tests/php/modules/masterbar/data/admin-menu.php' );
63
64
		static::$menu_data    = $menu;
65
		static::$submenu_data = $submenu;
66
		static::$domain       = wp_parse_url( get_home_url(), PHP_URL_HOST );
0 ignored issues
show
Documentation Bug introduced by
It seems like wp_parse_url(get_home_url(), PHP_URL_HOST) can also be of type false. However, the property $domain is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
67
68
		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...
69
		static::$admin_menu = Admin_Menu::get_instance();
70
	}
71
72
	/**
73
	 * Set up data.
74
	 */
75
	public function setUp() {
76
		parent::setUp();
77
78
		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...
79
	}
80
81
	/**
82
	 * Reset data.
83
	 */
84
	public function tearDown() {
85
		global $menu, $submenu;
86
87
		$menu    = static::$menu_data;
88
		$submenu = static::$submenu_data;
89
90
		parent::tearDown();
91
	}
92
93
	/**
94
	 * Test get_instance.
95
	 *
96
	 * @covers ::get_instance
97
	 * @covers ::__construct
98
	 */
99
	public function test_get_instance() {
100
		$instance = Admin_Menu::get_instance();
101
102
		$this->assertInstanceOf( Admin_Menu::class, $instance );
103
		$this->assertSame( $instance, static::$admin_menu );
104
105
		$this->assertSame( 99999, has_action( 'admin_menu', array( $instance, 'reregister_menu_items' ) ) );
106
		$this->assertSame( 10, has_action( 'admin_enqueue_scripts', array( $instance, 'enqueue_scripts' ) ) );
107
	}
108
109
	/**
110
	 * Tests add_admin_menu_separator
111
	 *
112
	 * @covers ::add_admin_menu_separator
113
	 */
114
	public function test_add_admin_menu_separator() {
115
		global $menu;
116
117
		// Start with a clean slate.
118
		$temp_menu = $menu;
119
		$menu      = array();
120
121
		static::$admin_menu->add_admin_menu_separator( 15 );
122
		static::$admin_menu->add_admin_menu_separator( 10, 'manage_options' );
123
124
		$this->assertSame( array( 10, 15 ), array_keys( $menu ), 'Menu should be ordered by position parameter.' );
125
		$this->assertSame( 'manage_options', $menu[10][1] );
126
		$this->assertSame( 'separator-custom-5', $menu[10][2] );
127
		$this->assertSame( 'read', $menu[15][1] );
128
		$this->assertSame( 'separator-custom-4', $menu[15][2] );
129
130
		// Restore filtered $menu.
131
		$menu = $temp_menu;
132
	}
133
134
	/**
135
	 * Test_Admin_Menu.
136
	 *
137
	 * @covers ::reregister_menu_items
138
	 */
139
	public function test_admin_menu_output() {
140
		global $menu, $submenu;
141
142
		static::$admin_menu->reregister_menu_items();
143
144
		$this->assertSame(
145
			array_keys( $menu ),
146
			array( 2, 3, '3.86682', 4, 5, 10, 15, 20, 25, 59, 60, 65, 70, 75, 80 ),
147
			'Admin menu should not have unexpected top menu items.'
148
		);
149
150
		$this->assertEquals( static::$menu_data[80], $menu[80], 'Settings menu should stay the same.' );
151
		$this->assertEquals( static::$submenu_data[''], $submenu[''], 'Submenu items without parent should stay the same.' );
152
	}
153
154
	/**
155
	 * Tests add_browse_sites_link.
156
	 *
157
	 * @covers ::add_browse_sites_link
158
	 */
159
	public function test_add_browse_sites_link() {
160
		if ( ! is_multisite() ) {
161
			$this->markTestSkipped( 'Only used on multisite' );
162
		}
163
		global $menu;
164
165
		static::$admin_menu->add_browse_sites_link();
166
		$this->assertArrayNotHasKey( 0, $menu );
167
168
		// Give user a second site.
169
		$blog_id = $this->factory->blog->create();
170
		add_user_to_blog( $blog_id, get_current_user_id(), 'editor' );
171
172
		static::$admin_menu->add_browse_sites_link();
173
174
		$browse_sites_menu_item = array(
175
			'Browse sites',
176
			'read',
177
			'https://wordpress.com/home',
178
			'site-switcher',
179
			'menu-top toplevel_page_https://wordpress.com/home',
180
			'toplevel_page_https://wordpress.com/home',
181
			'dashicons-arrow-left-alt2',
182
		);
183
		$this->assertSame( $menu[0], $browse_sites_menu_item );
184
185
		remove_user_from_blog( get_current_user_id(), $blog_id );
186
	}
187
188
	/**
189
	 * Tests add_new_site_link.
190
	 *
191
	 * @covers ::add_new_site_link
192
	 */
193
	public function test_add_new_site_link() {
194
		global $menu;
195
196
		static::$admin_menu->add_new_site_link();
197
198
		$new_site_menu_item = array(
199
			'Add new site',
200
			'read',
201
			'https://wordpress.com/start',
202
			'Add new site',
203
			'menu-top toplevel_page_https://wordpress.com/start',
204
			'toplevel_page_https://wordpress.com/start',
205
			'dashicons-plus-alt',
206
		);
207
		$this->assertSame( $menu[1002], $new_site_menu_item ); // 1001 is the separator position, 1002 is the link position
208
	}
209
210
	/**
211
	 * Tests add_site_card_menu
212
	 *
213
	 * @covers ::add_site_card_menu
214
	 */
215
	public function test_add_site_card_menu() {
216
		global $menu;
217
218
		static::$admin_menu->add_site_card_menu( static::$domain );
219
220
		$home_url            = home_url();
221
		$site_card_menu_item = array(
222
			// phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired
223
			"
224
<div class=\"site__info\">
225
	<div class=\"site__title\">Test Blog</div>
226
	<div class=\"site__domain\">" . static::$domain . "</div>
227
\t
228
</div>",
229
			'read',
230
			$home_url,
231
			'site-card',
232
			'menu-top toplevel_page_' . $home_url,
233
			'toplevel_page_' . $home_url,
234
			'data:image/svg+xml,%3Csvg%20class%3D%22gridicon%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Ctitle%3EGlobe%3C%2Ftitle%3E%3Crect%20fill-opacity%3D%220%22%20x%3D%220%22%20width%3D%2224%22%20height%3D%2224%22%2F%3E%3Cg%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M12%202C6.477%202%202%206.477%202%2012s4.477%2010%2010%2010%2010-4.477%2010-10S17.523%202%2012%202zm0%2018l2-2%201-1v-2h-2v-1l-1-1H9v3l2%202v1.93c-3.94-.494-7-3.858-7-7.93l1%201h2v-2h2l3-3V6h-2L9%205v-.41C9.927%204.21%2010.94%204%2012%204s2.073.212%203%20.59V6l-1%201v2l1%201%203.13-3.13c.752.897%201.304%201.964%201.606%203.13H18l-2%202v2l1%201h2l.286.286C18.03%2018.06%2015.24%2020%2012%2020z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E',
235
		);
236
237
		$this->assertEquals( $menu[1], $site_card_menu_item );
238
	}
239
240
	/**
241
	 * Tests set_site_card_menu_class
242
	 *
243
	 * @covers ::set_site_card_menu_class
244
	 */
245
	public function test_set_site_card_menu_class() {
246
		global $menu;
247
248
		static::$admin_menu->add_site_card_menu( static::$domain );
249
250
		$menu = static::$admin_menu->set_site_card_menu_class( $menu );
251
		$this->assertNotContains( 'has-site-icon', $menu[1][4] );
252
253
		// Atomic fallback site icon counts as no site icon.
254
		add_filter( 'get_site_icon_url', array( $this, 'wpcomsh_site_icon_url' ) );
255
		$menu = static::$admin_menu->set_site_card_menu_class( $menu );
256
		remove_filter( 'get_site_icon_url', array( $this, 'wpcomsh_site_icon_url' ) );
257
		$this->assertNotContains( 'has-site-icon', $menu[1][4] );
258
259
		// Custom site icon triggers CSS class.
260
		add_filter( 'get_site_icon_url', array( $this, 'custom_site_icon_url' ) );
261
		$menu = static::$admin_menu->set_site_card_menu_class( $menu );
262
		remove_filter( 'get_site_icon_url', array( $this, 'custom_site_icon_url' ) );
263
		$this->assertContains( 'has-site-icon', $menu[1][4] );
264
	}
265
266
	/**
267
	 * Shim wpcomsh fallback site icon.
268
	 *
269
	 * @return string
270
	 */
271
	public function wpcomsh_site_icon_url() {
272
		return 'https://s0.wp.com/i/webclip.png';
273
	}
274
275
	/**
276
	 * Custom site icon.
277
	 *
278
	 * @return string
279
	 */
280
	public function custom_site_icon_url() {
281
		return 'https://s0.wp.com/i/jetpack.png';
282
	}
283
284
	/**
285
	 * Tests add_my_home_menu
286
	 *
287
	 * @covers ::add_my_home_menu
288
	 */
289
	public function test_add_my_home_menu() {
290
		global $menu, $submenu;
291
292
		static::$admin_menu->add_my_home_menu( static::$domain );
293
294
		$slug = 'https://wordpress.com/home/' . static::$domain;
295
296
		$my_home_menu_item = array(
297
			'My Home',
298
			'read',
299
			$slug,
300
			'My Home',
301
			'menu-top toplevel_page_' . $slug,
302
			'toplevel_page_' . $slug,
303
			'dashicons-admin-home',
304
		);
305
		$this->assertSame( $menu[2], $my_home_menu_item );
306
307
		// Has My Home submenu item when there are other submenu items.
308
		$my_home_submenu_item = array(
309
			'My Home',
310
			'read',
311
			$slug,
312
			'My Home',
313
		);
314
		$this->assertContains( $my_home_submenu_item, $submenu[ $slug ] );
315
		// Reset data.
316
		$menu    = static::$menu_data;
317
		$submenu = static::$submenu_data;
318
319
		// Has no ny Home submenu when there are no other submenus.
320
		$submenu['index.php'] = array(
321
			0 => array( 'Home', 'read', 'index.php' ),
322
		);
323
324
		static::$admin_menu->add_my_home_menu( static::$domain );
325
326
		$this->assertArrayNotHasKey( 'https://wordpress.com/home/' . static::$domain, $submenu );
327
	}
328
329
	/**
330
	 * Tests add_stats_menu
331
	 *
332
	 * @covers ::add_stats_menu
333
	 */
334
	public function test_add_stats_menu() {
335
		global $menu, $submenu;
336
337
		static::$admin_menu->add_stats_menu( static::$domain );
338
339
		$menu_title = __( 'Stats', 'jetpack' );
340
341
		if ( ! defined( 'TESTING_IN_JETPACK' ) || ! TESTING_IN_JETPACK ) {
342
			$menu_title .= sprintf(
343
				'<img class="sidebar-unified__sparkline" width="80" height="20" src="%1$s" alt="%2$s">',
344
				esc_url( home_url( 'wp-includes/charts/admin-bar-hours-scale-2x.php?masterbar=1&s=' . get_current_blog_id() ) ),
345
				esc_attr__( 'Hourly views', 'jetpack' )
346
			);
347
		}
348
		$stats_menu_item = array(
349
			$menu_title,
350
			'edit_posts',
351
			'https://wordpress.com/stats/day/' . static::$domain,
352
			'Stats',
353
			'menu-top toplevel_page_https://wordpress.com/stats/day/' . static::$domain,
354
			'toplevel_page_https://wordpress.com/stats/day/' . static::$domain,
355
			'dashicons-chart-bar',
356
		);
357
358
		$this->assertSame( $menu['3.86682'], $stats_menu_item );
359
		$this->assertArrayNotHasKey( 'https://wordpress.com/stats/day/' . static::$domain, $submenu );
360
	}
361
362
	/**
363
	 * Tests add_wpcom_upgrades_menu
364
	 *
365
	 * @covers ::add_wpcom_upgrades_menu
366
	 */
367
	public function test_add_wpcom_upgrades_menu() {
368
		global $menu, $submenu;
369
370
		add_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
371
		static::$admin_menu->add_upgrades_menu( static::$domain );
372
		remove_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
373
374
		$slug = 'https://wordpress.com/plans/' . static::$domain;
375
376
		$upgrades_menu_item = array(
377
			'Upgrades',
378
			'manage_options',
379
			$slug,
380
			'Upgrades',
381
			'menu-top toplevel_page_https://wordpress.com/plans/' . static::$domain,
382
			'toplevel_page_https://wordpress.com/plans/' . static::$domain,
383
			'dashicons-cart',
384
		);
385
		$this->assertSame( $menu['4.80608'], $upgrades_menu_item );
386
387
		$plans_submenu_item = array(
388
			'Plans',
389
			'manage_options',
390
			$slug,
391
			'Plans',
392
		);
393
		$this->assertContains( $plans_submenu_item, $submenu[ $slug ] );
394
395
		$domains_submenu_item = array(
396
			'Domains',
397
			'manage_options',
398
			'https://wordpress.com/domains/manage/' . static::$domain,
399
			'Domains',
400
		);
401
		$this->assertContains( $domains_submenu_item, $submenu[ $slug ] );
402
403
		$purchases_submenu_item = array(
404
			'Purchases',
405
			'manage_options',
406
			'https://wordpress.com/purchases/subscriptions/' . static::$domain,
407
			'Purchases',
408
		);
409
		$this->assertContains( $purchases_submenu_item, $submenu[ $slug ] );
410
	}
411
412
	/**
413
	 * Tests add_jetpack_upgrades_menu
414
	 *
415
	 * @covers ::add_jetpack_upgrades_menu
416
	 */
417 View Code Duplication
	public function test_add_jetpack_upgrades_menu() {
418
		global $menu, $submenu;
419
420
		static::$admin_menu->add_upgrades_menu( static::$domain );
421
422
		$slug = 'https://wordpress.com/plans/' . static::$domain;
423
424
		$upgrades_menu_item = array(
425
			'Upgrades',
426
			'manage_options',
427
			$slug,
428
			'Upgrades',
429
			'menu-top toplevel_page_https://wordpress.com/plans/' . static::$domain,
430
			'toplevel_page_https://wordpress.com/plans/' . static::$domain,
431
			'dashicons-cart',
432
		);
433
		$this->assertSame( $menu['4.80608'], $upgrades_menu_item );
434
		$this->assertArrayNotHasKey( 'https://wordpress.com/domains/manage/' . static::$domain, $submenu );
435
	}
436
437
	/**
438
	 * Tests add_posts_menu
439
	 *
440
	 * @covers ::add_posts_menu
441
	 */
442 View Code Duplication
	public function test_add_posts_menu() {
443
		global $menu, $submenu;
444
445
		static::$admin_menu->add_posts_menu( static::$domain );
446
447
		$posts_menu_item = array(
448
			'Posts',
449
			'edit_posts',
450
			'https://wordpress.com/posts/' . static::$domain,
451
			'Posts',
452
			'menu-top toplevel_page_https://wordpress.com/posts/' . static::$domain,
453
			'toplevel_page_https://wordpress.com/posts/' . static::$domain,
454
			'dashicons-admin-post',
455
		);
456
457
		$this->assertSame( $menu[5], $posts_menu_item );
458
		$this->assertArrayNotHasKey( 'edit.php', $submenu );
459
	}
460
461
	/**
462
	 * Tests add_media_menu
463
	 *
464
	 * @covers ::add_media_menu
465
	 */
466
	public function test_add_media_menu() {
467
		global $menu, $submenu;
468
469
		static::$admin_menu->add_media_menu( static::$domain );
470
471
		$slug = 'https://wordpress.com/media/' . static::$domain;
472
473
		$media_menu_item = array(
474
			'Media',
475
			'upload_files',
476
			$slug,
477
			'Media',
478
			'menu-top toplevel_page_' . $slug,
479
			'toplevel_page_' . $slug,
480
			'dashicons-admin-media',
481
		);
482
483
		$this->assertSame( $menu[10], $media_menu_item );
484
		$this->assertArrayNotHasKey( $slug, $submenu );
485
486
		$library_submenu_item = array(
487
			'Library',
488
			'upload_files',
489
			'upload.php',
490
		);
491
		$this->assertNotContains( $library_submenu_item, $submenu['upload.php'] );
492
493
		$add_new_submenu_item = array(
494
			'Add New',
495
			'upload_files',
496
			'media-new.php',
497
		);
498
		$this->assertNotContains( $add_new_submenu_item, $submenu['upload.php'] );
499
	}
500
501
	/**
502
	 * Tests add_page_menu
503
	 *
504
	 * @covers ::add_page_menu
505
	 */
506 View Code Duplication
	public function test_add_page_menu() {
507
		global $menu, $submenu;
508
509
		static::$admin_menu->add_page_menu( static::$domain );
510
511
		$posts_menu_item = array(
512
			'Pages',
513
			'edit_pages',
514
			'https://wordpress.com/pages/' . static::$domain,
515
			'Pages',
516
			'menu-top toplevel_page_https://wordpress.com/pages/' . static::$domain,
517
			'toplevel_page_https://wordpress.com/pages/' . static::$domain,
518
			'dashicons-admin-page',
519
		);
520
521
		$this->assertSame( $menu[20], $posts_menu_item );
522
		$this->assertEmpty( $submenu['edit.php?post_type=page'] );
523
	}
524
525
	/**
526
	 * Tests add_comments_menu
527
	 *
528
	 * @covers ::add_comments_menu
529
	 */
530
	public function test_add_comments_menu() {
531
		global $menu, $submenu;
532
533
		// Only users that can edit posts get to see the comments menu.
534
		wp_set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
535
		$menu = array();
536
		static::$admin_menu->add_comments_menu( static::$domain );
537
		$this->assertEmpty( $menu );
538
539
		// Reset.
540
		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...
541
		$menu = static::$menu_data;
542
543
		static::$admin_menu->add_comments_menu( static::$domain );
544
545
		$comments_menu_item = array(
546
			'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>',
547
			'edit_posts',
548
			'https://wordpress.com/comments/all/' . static::$domain,
549
			'Comments',
550
			'menu-top toplevel_page_https://wordpress.com/comments/all/' . static::$domain,
551
			'toplevel_page_https://wordpress.com/comments/all/' . static::$domain,
552
			'dashicons-admin-comments',
553
		);
554
555
		$this->assertSame( $menu[25], $comments_menu_item );
556
		$this->assertEmpty( $submenu['edit-comments.php'] );
557
	}
558
559
	/**
560
	 * Tests jetpack_parent_file
561
	 *
562
	 * @covers ::jetpack_parent_file
563
	 */
564
	public function test_jetpack_parent_file() {
565
		$parent_file = 'edit.php';
566
		$this->assertSame( $parent_file, static::$admin_menu->jetpack_parent_file( $parent_file ) );
567
568
		$this->assertSame(
569
			'https://wordpress.com/activity-log/' . static::$domain,
570
			static::$admin_menu->jetpack_parent_file( 'jetpack' )
571
		);
572
	}
573
574
	/**
575
	 * Tests add_appearance_menu
576
	 *
577
	 * @covers ::add_appearance_menu
578
	 */
579
	public function test_add_appearance_menu() {
580
		global $menu, $submenu;
581
582
		static::$admin_menu->add_appearance_menu( static::$domain );
583
584
		$slug = 'https://wordpress.com/customize/' . static::$domain;
585
586
		$appearance_menu_item = array(
587
			'Appearance',
588
			'customize',
589
			$slug,
590
			'Appearance',
591
			'menu-top toplevel_page_' . $slug,
592
			'toplevel_page_' . $slug,
593
			'dashicons-admin-appearance',
594
		);
595
596
		$this->assertSame( $menu[60], $appearance_menu_item );
597
		$this->assertArrayNotHasKey( 'themes.php', $submenu );
598
599
		$customize_submenu_item = array(
600
			'Customize',
601
			'customize',
602
			'https://wordpress.com/customize/' . static::$domain,
603
			'Customize',
604
		);
605
		$this->assertContains( $customize_submenu_item, $submenu[ $slug ] );
606
607
		$themes_submenu_item = array(
608
			'Themes',
609
			'switch_themes',
610
			'https://wordpress.com/themes/' . static::$domain,
611
			'Themes',
612
		);
613
		$this->assertContains( $themes_submenu_item, $submenu[ $slug ] );
614
615
		$widgets_submenu_item = array(
616
			'Widgets',
617
			'customize',
618
			'https://wordpress.com/customize/' . static::$domain . '?autofocus%5Bpanel%5D=widgets',
619
			'Widgets',
620
		);
621
		$this->assertContains( $widgets_submenu_item, $submenu[ $slug ] );
622
623
		$menus_submenu_item = array(
624
			'Menus',
625
			'customize',
626
			'https://wordpress.com/customize/' . static::$domain . '?autofocus%5Bpanel%5D=nav_menus',
627
			'Menus',
628
		);
629
		$this->assertContains( $menus_submenu_item, $submenu[ $slug ] );
630
	}
631
632
	/**
633
	 * Tests add_plugins_menu
634
	 *
635
	 * @covers ::add_plugins_menu
636
	 */
637
	public function test_add_plugins_menu() {
638
		global $menu, $submenu;
639
640
		add_filter( 'wp_get_update_data', array( $this, 'mock_update_data' ) );
641
		add_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
642
643
		static::$admin_menu->add_plugins_menu( static::$domain );
644
645
		remove_filter( 'wp_get_update_data', array( $this, 'mock_update_data' ) );
646
		remove_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
647
648
		$slug  = 'https://wordpress.com/plugins/' . static::$domain;
649
		$label = is_multisite() ? 'Plugins ' : 'Plugins <span class="update-plugins count-0"><span class="plugin-count">0</span></span>';
650
651
		$plugins_menu_item = array(
652
			$label,
653
			'activate_plugins',
654
			$slug,
655
			'Plugins',
656
			'menu-top toplevel_page_' . $slug,
657
			'toplevel_page_' . $slug,
658
			'dashicons-admin-plugins',
659
		);
660
661
		$this->assertEquals( $plugins_menu_item, $menu[65] );
662
		$this->assertArrayNotHasKey( 'plugins.php', $submenu );
663
664
		$editor_submenu_item = array(
665
			'Plugin Editor',
666
			'edit_plugins',
667
			'plugin-editor.php',
668
		);
669
		$this->assertNotContains( $editor_submenu_item, $submenu[ $slug ] );
670
	}
671
672
	/**
673
	 * Filters the returned array of update data for plugins, themes, and WordPress core.
674
	 */
675
	public function mock_update_data() {
676
		return array(
677
			'counts' => array(
678
				'plugins'      => 0,
679
				'themes'       => 0,
680
				'translations' => 0,
681
				'wordpress'    => 0,
682
			),
683
			'title'  => '',
684
		);
685
	}
686
687
	/**
688
	 * Tests add_users_menu
689
	 *
690
	 * @covers ::add_users_menu
691
	 */
692
	public function test_add_users_menu() {
693
		global $menu, $submenu;
694
695
		// Current user can't list users.
696
		wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) );
697
		$menu = array();
698
699
		add_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
700
		static::$admin_menu->add_users_menu( static::$domain, true );
701
		remove_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
702
703
		$profile_menu_item = array(
704
			'My Profile',
705
			'read',
706
			'https://wordpress.com/me',
707
			'My Profile',
708
			'menu-top toplevel_page_https://wordpress.com/me',
709
			'toplevel_page_https://wordpress.com/me',
710
			'dashicons-admin-users',
711
		);
712
713
		$this->assertSame( $menu[70], $profile_menu_item );
714
715
		$account_submenu_item = array(
716
			'Account Settings',
717
			'read',
718
			'https://wordpress.com/me/account',
719
			'Account Settings',
720
		);
721
		$this->assertContains( $account_submenu_item, $submenu['https://wordpress.com/me'] );
722
		$this->assertArrayNotHasKey( 'profile.php', $submenu );
723
724
		// Reset.
725
		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...
726
		$menu = static::$menu_data;
727
728
		static::$admin_menu->add_users_menu( static::$domain );
729
730
		$slug = 'https://wordpress.com/people/team/' . static::$domain;
731
732
		$users_menu_item = array(
733
			'Users',
734
			'list_users',
735
			$slug,
736
			'Users',
737
			'menu-top toplevel_page_' . $slug,
738
			'toplevel_page_' . $slug,
739
			'dashicons-admin-users',
740
		);
741
		$this->assertSame( $menu[70], $users_menu_item );
742
		$this->assertEmpty( $submenu['users.php'] );
743
744
		$all_people_submenu_item = array(
745
			'All People',
746
			'list_users',
747
			$slug,
748
			'All People',
749
		);
750
		$this->assertContains( $all_people_submenu_item, $submenu[ $slug ] );
751
752
		$add_new_submenu_item = array(
753
			'Add New',
754
			'promote_users',
755
			'https://wordpress.com/people/new/' . static::$domain,
756
			'Add New',
757
		);
758
		$this->assertContains( $add_new_submenu_item, $submenu[ $slug ] );
759
760
		$profile_submenu_item = array(
761
			'My Profile',
762
			'read',
763
			'https://wordpress.com/me',
764
			'My Profile',
765
		);
766
		$this->assertContains( $profile_submenu_item, $submenu[ $slug ] );
767
768
		$account_submenu_item = array(
769
			'Account Settings',
770
			'read',
771
			'https://wordpress.com/me/account',
772
			'Account Settings',
773
		);
774
		$this->assertContains( $account_submenu_item, $submenu[ $slug ] );
775
	}
776
777
	/**
778
	 * Tests add_tools_menu
779
	 *
780
	 * @covers ::add_tools_menu
781
	 */
782
	public function test_add_tools_menu() {
783
		global $menu, $submenu;
784
785
		add_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
786
		$slug = 'https://wordpress.com/marketing/tools/' . static::$domain;
787
		static::$admin_menu->add_tools_menu( static::$domain );
788
		remove_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
789
790
		$tools_menu_item = array(
791
			'Tools',
792
			'manage_options',
793
			$slug,
794
			'Tools',
795
			'menu-top toplevel_page_' . $slug,
796
			'toplevel_page_' . $slug,
797
			'dashicons-admin-tools',
798
		);
799
800
		$this->assertSame( $menu[75], $tools_menu_item );
801
		$this->assertArrayNotHasKey( 'tools.php', $submenu );
802
803
		// Contains the following menu items.
804
805
		$marketing_submenu_item = array(
806
			'Marketing',
807
			'manage_options',
808
			'https://wordpress.com/marketing/tools/' . static::$domain,
809
			'Marketing',
810
		);
811
		$this->assertContains( $marketing_submenu_item, $submenu[ $slug ] );
812
813
		$earn_submenu_item = array(
814
			'Earn',
815
			'manage_options',
816
			'https://wordpress.com/earn/' . static::$domain,
817
			'Earn',
818
		);
819
		$this->assertContains( $earn_submenu_item, $submenu[ $slug ] );
820
821
		$import_submenu_item = array(
822
			'Import',
823
			'import',
824
			'https://wordpress.com/import/' . static::$domain,
825
			'Import',
826
		);
827
		$this->assertContains( $import_submenu_item, $submenu[ $slug ] );
828
829
		$export_submenu_item = array(
830
			'Export',
831
			'export',
832
			'https://wordpress.com/export/' . static::$domain,
833
			'Export',
834
		);
835
		$this->assertContains( $export_submenu_item, $submenu[ $slug ] );
836
837
		// NOT contains the following menu items.
838
839
		$tools_submenu_item = array(
840
			'Available Tools',
841
			'edit_posts',
842
			'tools.php',
843
		);
844
		$this->assertNotContains( $tools_submenu_item, $submenu[ $slug ] );
845
846
		$import_submenu_item = array(
847
			'Import',
848
			'import',
849
			'import.php',
850
		);
851
		$this->assertNotContains( $import_submenu_item, $submenu[ $slug ] );
852
853
		$export_submenu_item = array(
854
			'Export',
855
			'export',
856
			'export.php',
857
		);
858
		$this->assertNotContains( $export_submenu_item, $submenu[ $slug ] );
859
	}
860
861
	/**
862
	 * Tests add_options_menu
863
	 *
864
	 * @covers ::add_options_menu
865
	 */
866
	public function test_add_options_menu() {
867
		global $submenu;
868
869
		add_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
870
		static::$admin_menu->add_options_menu( static::$domain );
871
		remove_filter( 'jetpack_admin_menu_is_wpcom', '__return_true' );
872
873
		$this->assertNotContains( 'options-discussion.php', $submenu['options-general.php'] );
874
		$this->assertNotContains( 'options-writing.php', $submenu['options-general.php'] );
875
876
		$this->assertContains( 'Hosting Configuration', $submenu['options-general.php'][6] );
877
	}
878
879
	/**
880
	 * Tests migrate_submenus
881
	 *
882
	 * @covers ::migrate_submenus
883
	 */
884
	public function test_migrate_submenus() {
885
		global $submenu;
886
887
		$new_slug = 'made-up-slug';
888
889
		// Start with a clean slate.
890
		$temp_submenu = $submenu;
891
		$submenu      = static::$submenu_data;
892
893
		// New slug doesn't exist yet.
894
		static::$admin_menu->migrate_submenus( 'edit.php', $new_slug );
895
		$this->assertArrayNotHasKey( 'edit.php', $submenu );
896
		$this->assertSame( static::$submenu_data['edit.php'], $submenu[ $new_slug ] );
897
898
		// New slug exists.
899
		static::$admin_menu->migrate_submenus( 'upload.php', $new_slug );
900
		$this->assertArrayNotHasKey( 'upload.php', $submenu );
901
		$expected = array_replace( static::$submenu_data['edit.php'], static::$submenu_data['upload.php'] );
902
		$this->assertSame( $expected, $submenu[ $new_slug ] );
903
904
		// Old slug doesn't exist.
905
		$this->assertArrayNotHasKey( 'unkown', $submenu );
906
		$pre_migration = $submenu;
907
		static::$admin_menu->migrate_submenus( 'unkown', $new_slug );
908
		$this->assertSame( $pre_migration, $submenu );
909
910
		// Slugs are the same.
911
		$this->assertArrayHasKey( 'index.php', $submenu );
912
		$pre_migration = $submenu;
913
		static::$admin_menu->migrate_submenus( 'index.php', 'index.php' );
914
		$this->assertSame( $pre_migration, $submenu );
915
916
		// Restore filtered $submenu.
917
		$submenu = $temp_submenu;
918
	}
919
}
920