Completed
Push — e2e/e2e-page-actions ( 1f4d85...20a111 )
by
unknown
10:03
created

Test_Atomic_Admin_Menu::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 12
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * Tests for Atomic_Admin_Menu class.
4
 *
5
 * @package automattic/jetpack
6
 */
7
8
use Automattic\Jetpack\Dashboard_Customizations\Atomic_Admin_Menu;
9
use Automattic\Jetpack\Status;
10
11
require_jetpack_file( 'modules/masterbar/admin-menu/class-atomic-admin-menu.php' );
12
require_jetpack_file( 'tests/php/modules/masterbar/data/admin-menu.php' );
13
14
/**
15
 * Class Test_Atomic_Admin_Menu.
16
 *
17
 * @coversDefaultClass Automattic\Jetpack\Dashboard_Customizations\Atomic_Admin_Menu
18
 */
19
class Test_Atomic_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
	 * Whether this testsuite is run on WP.com.
44
	 *
45
	 * @var bool
46
	 */
47
	public static $is_wpcom;
48
49
	/**
50
	 * Admin menu instance.
51
	 *
52
	 * @var Atomic_Admin_Menu
53
	 */
54
	public static $admin_menu;
55
56
	/**
57
	 * Mock user ID.
58
	 *
59
	 * @var int
60
	 */
61
	private static $user_id = 0;
62
63
	/**
64
	 * Create shared fixtures.
65
	 *
66
	 * @param WP_UnitTest_Factory $factory Fixture factory.
67
	 */
68 View Code Duplication
	public static function wpSetUpBeforeClass( $factory ) {
69
		static::$domain       = ( new Status() )->get_site_suffix();
70
		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...
71
		static::$menu_data    = get_menu_fixture();
72
		static::$submenu_data = get_submenu_fixture();
73
	}
74
75
	/**
76
	 * Set up data.
77
	 */
78 View Code Duplication
	public function setUp() {
79
		parent::setUp();
80
		global $menu, $submenu;
81
82
		// Initialize in setUp so it registers hooks for every test.
83
		static::$admin_menu = Atomic_Admin_Menu::get_instance();
84
85
		$menu    = static::$menu_data;
86
		$submenu = static::$submenu_data;
87
88
		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...
89
	}
90
91
	/**
92
	 * Test get_instance.
93
	 *
94
	 * @covers ::get_instance
95
	 * @covers ::__construct
96
	 */
97 View Code Duplication
	public function test_get_instance() {
98
		$instance = Atomic_Admin_Menu::get_instance();
99
100
		$this->assertInstanceOf( Atomic_Admin_Menu::class, $instance );
101
		$this->assertSame( $instance, static::$admin_menu );
102
103
		$this->assertSame( 99999, has_action( 'admin_menu', array( $instance, 'reregister_menu_items' ) ) );
104
		$this->assertSame( 10, has_action( 'admin_enqueue_scripts', array( $instance, 'enqueue_scripts' ) ) );
105
	}
106
107
	/**
108
	 * Tests add_browse_sites_link.
109
	 *
110
	 * @covers ::add_browse_sites_link
111
	 */
112
	public function test_add_browse_sites_link() {
113
		global $menu;
114
115
		// No output when executed in single site mode.
116
		static::$admin_menu->add_browse_sites_link();
117
		$this->assertArrayNotHasKey( 0, $menu );
118
	}
119
120
	/**
121
	 * Tests add_browse_sites_link.
122
	 *
123
	 * @covers ::add_browse_sites_link
124
	 */
125
	public function test_add_browse_sites_link_multisite() {
126
		if ( ! is_multisite() ) {
127
			$this->markTestSkipped( 'Only used on multisite' );
128
		}
129
130
		global $menu;
131
132
		// No output when user has just one site.
133
		static::$admin_menu->add_browse_sites_link();
134
		$this->assertArrayNotHasKey( 0, $menu );
135
136
		// Give user a second site.
137
		update_user_option( static::$user_id, 'wpcom_site_count', 2 );
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...
138
139
		static::$admin_menu->add_browse_sites_link();
140
141
		$browse_sites_menu_item = array(
142
			'Browse sites',
143
			'read',
144
			'https://wordpress.com/home',
145
			'site-switcher',
146
			'menu-top toplevel_page_https://wordpress.com/home',
147
			'toplevel_page_https://wordpress.com/home',
148
			'dashicons-arrow-left-alt2',
149
		);
150
		$this->assertSame( $menu[0], $browse_sites_menu_item );
151
152
		delete_user_option( static::$user_id, 'wpcom_site_count' );
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...
153
	}
154
155
	/**
156
	 * Tests add_new_site_link.
157
	 *
158
	 * @covers ::add_new_site_link
159
	 */
160
	public function test_add_new_site_link() {
161
		global $menu;
162
163
		// Set jetpack user data.
164
		update_user_option( static::$user_id, 'wpcom_site_count', 1 );
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...
165
166
		static::$admin_menu->add_new_site_link();
167
168
		$new_site_menu_item = array(
169
			'Add new site',
170
			'read',
171
			'https://wordpress.com/start?ref=calypso-sidebar',
172
			'Add new site',
173
			'menu-top toplevel_page_https://wordpress.com/start?ref=calypso-sidebar',
174
			'toplevel_page_https://wordpress.com/start?ref=calypso-sidebar',
175
			'dashicons-plus-alt',
176
		);
177
		$this->assertSame( $menu[1002], $new_site_menu_item ); // 1001 is the separator position, 1002 is the link position
178
179
		delete_user_option( static::$user_id, 'wpcom_site_count' );
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...
180
	}
181
182
	/**
183
	 * Tests add_site_card_menu
184
	 *
185
	 * @covers ::add_site_card_menu
186
	 */
187
	public function test_add_site_card_menu() {
188
		global $menu;
189
190
		if ( ! function_exists( 'site_is_private' ) ) {
191
			function site_is_private() { // phpcs:ignore
192
				return false;
193
			}
194
		}
195
		static::$admin_menu->add_site_card_menu();
196
197
		$home_url            = home_url();
198
		$site_card_menu_item = array(
199
			// phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired
200
			'
201
<div class="site__info">
202
	<div class="site__title">' . get_option( 'blogname' ) . '</div>
203
	<div class="site__domain">' . static::$domain . "</div>\n\t\n</div>",
204
			'read',
205
			$home_url,
206
			'site-card',
207
			'menu-top toplevel_page_' . $home_url,
208
			'toplevel_page_' . $home_url,
209
			'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',
210
		);
211
212
		$this->assertEquals( $menu[1], $site_card_menu_item );
213
	}
214
215
	/**
216
	 * Tests set_site_card_menu_class
217
	 *
218
	 * @covers ::set_site_card_menu_class
219
	 */
220
	public function test_set_site_card_menu_class() {
221
		global $menu;
222
223
		if ( ! function_exists( 'site_is_private' ) ) {
224
			function site_is_private() { // phpcs:ignore
0 ignored issues
show
Best Practice introduced by
The function site_is_private() has been defined more than once; this definition is ignored, only the first definition in this file (L191-193) is considered.

This check looks for functions that have already been defined in the same file.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
225
				return false;
226
			}
227
		}
228
229
		static::$admin_menu->add_site_card_menu();
230
231
		$menu = static::$admin_menu->set_site_card_menu_class( $menu );
232
		$this->assertNotContains( 'has-site-icon', $menu[1][4] );
233
234
		// Atomic fallback site icon counts as no site icon.
235
		add_filter( 'get_site_icon_url', array( $this, 'wpcomsh_site_icon_url' ) );
236
		$menu = static::$admin_menu->set_site_card_menu_class( $menu );
237
		remove_filter( 'get_site_icon_url', array( $this, 'wpcomsh_site_icon_url' ) );
238
		$this->assertNotContains( 'has-site-icon', $menu[1][4] );
239
240
		// Custom site icon triggers CSS class.
241
		add_filter( 'get_site_icon_url', array( $this, 'custom_site_icon_url' ) );
242
		$menu = static::$admin_menu->set_site_card_menu_class( $menu );
243
		remove_filter( 'get_site_icon_url', array( $this, 'custom_site_icon_url' ) );
244
		$this->assertContains( 'has-site-icon', $menu[1][4] );
245
	}
246
247
	/**
248
	 * Shim wpcomsh fallback site icon.
249
	 *
250
	 * @return string
251
	 */
252
	public function wpcomsh_site_icon_url() {
253
		return 'https://s0.wp.com/i/webclip.png';
254
	}
255
256
	/**
257
	 * Custom site icon.
258
	 *
259
	 * @return string
260
	 */
261
	public function custom_site_icon_url() {
262
		return 'https://s0.wp.com/i/jetpack.png';
263
	}
264
265
	/**
266
	 * Tests add_upgrades_menu
267
	 *
268
	 * @covers ::add_upgrades_menu
269
	 */
270
	public function test_add_upgrades_menu() {
271
		global $submenu;
272
273
		static::$admin_menu->add_upgrades_menu();
274
275
		$this->assertSame( 'https://wordpress.com/domains/manage/' . static::$domain, array_pop( $submenu['paid-upgrades.php'] )[2] );
276
	}
277
278
	/**
279
	 * Tests add_tools_menu
280
	 *
281
	 * @covers ::add_tools_menu
282
	 */
283
	public function test_add_tools_menu() {
284
		global $submenu;
285
286
		static::$admin_menu->add_tools_menu();
287
288
		// Check Export menu item always links to WP Admin.
289
		$this->assertSame( 'export.php', $submenu['tools.php'][3][2] );
290
	}
291
292
	/**
293
	 * Tests add_options_menu
294
	 *
295
	 * @covers ::add_options_menu
296
	 */
297
	public function test_add_options_menu() {
298
		global $submenu, $menu;
299
300
		static::$admin_menu->add_options_menu();
301
		$this->assertSame( 'https://wordpress.com/hosting-config/' . static::$domain, $submenu['options-general.php'][6][2] );
302
		$this->assertSame( 'options-writing.php', array_pop( $submenu['options-general.php'] )[2] );
303
		$this->assertSame( 'options-general.php', array_pop( $submenu['options-general.php'] )[2] );
304
305
		// Reset.
306
		$menu    = static::$menu_data;
307
		$submenu = static::$submenu_data;
308
309
		static::$admin_menu->add_options_menu( true );
310
		$last_submenu = array_pop( $submenu['options-general.php'] );
311
		$this->assertNotSame( 'options-writing.php', $last_submenu[2] );
312
		$this->assertNotSame( 'options-general.php', $last_submenu[2] );
313
	}
314
315
	/**
316
	 * Tests add_plugins_menu
317
	 *
318
	 * @covers ::add_plugins_menu
319
	 */
320
	public function test_add_plugins_menu() {
321
		global $menu;
322
323
		static::$admin_menu->add_plugins_menu( false );
324
325
		// Check Plugins menu always links to WP Admin.
326
		$this->assertSame( 'plugins.php', $menu[65][2] );
327
	}
328
329
	/**
330
	 * Tests add_appearance_menu
331
	 *
332
	 * @covers ::add_appearance_menu
333
	 */
334
	public function test_add_appearance_menu() {
335
		global $submenu;
336
337
		static::$admin_menu->add_appearance_menu();
338
339
		// Multisite users don't have the `install_themes` capability by default,
340
		// so we have to make a dynamic check based on whether the current user can
341
		// install themes.
342
		if ( current_user_can( 'install_themes' ) ) {
343
			$this->assertSame( 'theme-install.php', $submenu['themes.php'][1][2] );
344
			// Check Customize menu always links to WP Admin.
345
			$this->assertSame( 'customize.php?return', $submenu['themes.php'][2][2] );
346
		} else {
347
			// Check Customize menu always links to WP Admin.
348
			$this->assertSame( 'customize.php?return', $submenu['themes.php'][6][2] );
349
		}
350
	}
351
352
	/**
353
	 * Tests add_users_menu
354
	 *
355
	 * @covers ::add_users_menu
356
	 */
357 View Code Duplication
	public function test_add_users_menu() {
358
		global $menu, $submenu;
359
360
		static::$admin_menu->add_users_menu();
361
		$this->assertSame( 'users.php', $submenu['users.php'][2][2] );
362
363
		// Reset.
364
		$menu    = static::$menu_data;
365
		$submenu = static::$submenu_data;
366
367
		static::$admin_menu->add_users_menu( true );
368
		$this->assertArrayNotHasKey( 2, $submenu['users.php'] );
369
	}
370
}
371