mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-07-01 15:50:09 +00:00
REST API: Introduce Menu management endpoints.
This commit introduces the `/wp/v2/menus`, `/wp/v2/menu-items` and `/wp/v2/menu-locations` REST API endpoints. These endpoints are fully available to users with the `edit_theme_options` capability, but can be read by any user who can edit a REST API available post type. The `nav_menu` taxonomy and `nav_menu_item` post type now map their capabilities to the `edit_theme_options` primitive capability. This allows developers to provide more fine-grained access control. However, if a developer is currently dynamically removing the `edit_theme_options` capability using `map_meta_cap`, they should use the `user_has_cap` filter instead. The `wp_update_nav_menu_item()` function has been adjusted to return an error if saving the menu item post or assigning the menu item to a menu generate an error. Lastly, a new menu item type is introduced, `block`, that can be used to store a Block as a menu item. Props andraganescu, antonvlasenko, dingo_d, dlh, isabel_brison, kadamwhite, Mamaduka, NateWr, noisysocks, peterwilsoncc, ryelle, schlessera, soean, Spacedmonkey, talldanwp, TimothyBlynJacobs, tobifjellner, westonruter, wpscholar, zieladam. Fixes #40878. git-svn-id: https://develop.svn.wordpress.org/trunk@52079 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -89,6 +89,14 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
|
||||
'/wp/v2/posts/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)',
|
||||
'/wp/v2/posts/(?P<id>[\\d]+)/autosaves',
|
||||
'/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)',
|
||||
'/wp/v2/menu-items',
|
||||
'/wp/v2/menu-items/(?P<id>[\d]+)',
|
||||
'/wp/v2/menu-items/(?P<id>[\d]+)/autosaves',
|
||||
'/wp/v2/menu-items/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)',
|
||||
'/wp/v2/menu-locations',
|
||||
'/wp/v2/menu-locations/(?P<location>[\w-]+)',
|
||||
'/wp/v2/menus',
|
||||
'/wp/v2/menus/(?P<id>[\d]+)',
|
||||
'/wp/v2/pages',
|
||||
'/wp/v2/pages/(?P<id>[\\d]+)',
|
||||
'/wp/v2/pages/(?P<parent>[\\d]+)/revisions',
|
||||
|
||||
@@ -68,7 +68,9 @@ class WP_Test_REST_Taxonomies_Controller extends WP_Test_REST_Controller_Testcas
|
||||
$request->set_param( 'context', 'edit' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$taxonomies = $this->get_public_taxonomies( get_taxonomies( '', 'objects' ) );
|
||||
$taxonomies = get_taxonomies( '', 'objects' );
|
||||
unset( $taxonomies['nav_menu'] ); // Menus are not editable by contributors.
|
||||
$taxonomies = $this->get_public_taxonomies( $taxonomies );
|
||||
$this->assertSame( count( $taxonomies ), count( $data ) );
|
||||
$this->assertSame( 'Categories', $data['category']['name'] );
|
||||
$this->assertSame( 'category', $data['category']['slug'] );
|
||||
|
||||
1152
tests/phpunit/tests/rest-api/wpRestMenuItemsController.php
Normal file
1152
tests/phpunit/tests/rest-api/wpRestMenuItemsController.php
Normal file
File diff suppressed because it is too large
Load Diff
207
tests/phpunit/tests/rest-api/wpRestMenuLocationsController.php
Normal file
207
tests/phpunit/tests/rest-api/wpRestMenuLocationsController.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_REST_Menu_Locations_Controller tests.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage REST_API
|
||||
* @since 5.9.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests for REST API for Menu locations.
|
||||
*
|
||||
* @group restapi
|
||||
*
|
||||
* @coversDefaultClass WP_REST_Menu_Locations_Controller
|
||||
*/
|
||||
class Tests_REST_WpRestMenuLocationsController extends WP_Test_REST_Controller_Testcase {
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $admin_id;
|
||||
|
||||
/**
|
||||
* Create fake data before our tests run.
|
||||
*
|
||||
* @param WP_UnitTest_Factory $factory Helper that lets us create fake data.
|
||||
*/
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
self::$admin_id = $factory->user->create(
|
||||
array(
|
||||
'role' => 'administrator',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up.
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
|
||||
// Unregister all nav menu locations.
|
||||
foreach ( array_keys( get_registered_nav_menus() ) as $location ) {
|
||||
unregister_nav_menu( $location );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register nav menu locations.
|
||||
*
|
||||
* @param array $locations Location slugs.
|
||||
*/
|
||||
public function register_nav_menu_locations( $locations ) {
|
||||
foreach ( $locations as $location ) {
|
||||
register_nav_menu( $location, ucfirst( $location ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::register_routes
|
||||
*/
|
||||
public function test_register_routes() {
|
||||
$routes = rest_get_server()->get_routes();
|
||||
$this->assertArrayHasKey( '/wp/v2/menu-locations', $routes );
|
||||
$this->assertCount( 1, $routes['/wp/v2/menu-locations'] );
|
||||
$this->assertArrayHasKey( '/wp/v2/menu-locations/(?P<location>[\w-]+)', $routes );
|
||||
$this->assertCount( 1, $routes['/wp/v2/menu-locations/(?P<location>[\w-]+)'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_context_param
|
||||
*/
|
||||
public function test_context_param() {
|
||||
// Collection.
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menu-locations' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
|
||||
$this->assertSame( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );
|
||||
$menu = 'primary';
|
||||
$this->register_nav_menu_locations( array( $menu ) );
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menu-locations/' . $menu );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
|
||||
$this->assertSame( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_items
|
||||
*/
|
||||
public function test_get_items() {
|
||||
$menus = array( 'primary', 'secondary' );
|
||||
$this->register_nav_menu_locations( array( 'primary', 'secondary' ) );
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menu-locations' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$data = array_values( $data );
|
||||
$this->assertCount( 2, $data );
|
||||
$names = wp_list_pluck( $data, 'name' );
|
||||
$descriptions = wp_list_pluck( $data, 'description' );
|
||||
$this->assertSame( $menus, $names );
|
||||
$menu_descriptions = array_map( 'ucfirst', $names );
|
||||
$this->assertSame( $menu_descriptions, $descriptions );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item
|
||||
*/
|
||||
public function test_get_item() {
|
||||
$menu = 'primary';
|
||||
$this->register_nav_menu_locations( array( $menu ) );
|
||||
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menu-locations/' . $menu );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertSame( $menu, $data['name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item
|
||||
*/
|
||||
public function test_get_item_invalid() {
|
||||
$menu = 'primary';
|
||||
$this->register_nav_menu_locations( array( $menu ) );
|
||||
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menu-locations/invalid' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertErrorResponse( 'rest_menu_location_invalid', $response, 404 );
|
||||
}
|
||||
|
||||
/**
|
||||
* The test_create_item() method does not exist for menu locations.
|
||||
*/
|
||||
public function test_create_item() {}
|
||||
|
||||
/**
|
||||
* The test_update_item() method does not exist for menu locations.
|
||||
*/
|
||||
public function test_update_item() {}
|
||||
|
||||
/**
|
||||
* The test_delete_item() method does not exist for menu locations.
|
||||
*/
|
||||
public function test_delete_item() {}
|
||||
|
||||
/**
|
||||
* The test_prepare_item() method does not exist for menu locations.
|
||||
*/
|
||||
public function test_prepare_item() {}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item_schema
|
||||
*/
|
||||
public function test_get_item_schema() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menu-locations' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertSame( 3, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'name', $properties );
|
||||
$this->assertArrayHasKey( 'description', $properties );
|
||||
$this->assertArrayHasKey( 'menu', $properties );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_items
|
||||
* @covers ::get_items_permissions_check
|
||||
*/
|
||||
public function test_get_items_menu_location_context_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menu-locations' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertErrorResponse( 'rest_cannot_view', $response, rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item
|
||||
* @covers ::get_item_permissions_check
|
||||
*/
|
||||
public function test_get_item_menu_location_context_without_permission() {
|
||||
$menu = 'primary';
|
||||
$this->register_nav_menu_locations( array( $menu ) );
|
||||
|
||||
wp_set_current_user( 0 );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menu-locations/' . $menu );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertErrorResponse( 'rest_cannot_view', $response, rest_authorization_required_code() );
|
||||
}
|
||||
}
|
||||
642
tests/phpunit/tests/rest-api/wpRestMenusController.php
Normal file
642
tests/phpunit/tests/rest-api/wpRestMenusController.php
Normal file
@@ -0,0 +1,642 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_REST_Menus_Controller tests
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage REST_API
|
||||
* @since 5.9.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests for REST API for Menus.
|
||||
*
|
||||
* @group restapi
|
||||
*
|
||||
* @coversDefaultClass WP_REST_Menus_Controller
|
||||
*/
|
||||
class Tests_REST_WpRestMenusController extends WP_Test_REST_Controller_Testcase {
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $menu_id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $admin_id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $editor_id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $subscriber_id;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TAXONOMY = 'nav_menu';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $per_page = 50;
|
||||
|
||||
/**
|
||||
* Create fake data before our tests run.
|
||||
*
|
||||
* @param WP_UnitTest_Factory $factory Helper that lets us create fake data.
|
||||
*/
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
self::$admin_id = $factory->user->create(
|
||||
array(
|
||||
'role' => 'administrator',
|
||||
)
|
||||
);
|
||||
self::$editor_id = $factory->user->create(
|
||||
array(
|
||||
'role' => 'editor',
|
||||
)
|
||||
);
|
||||
self::$subscriber_id = $factory->user->create(
|
||||
array(
|
||||
'role' => 'subscriber',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
// Unregister all nav menu locations.
|
||||
foreach ( array_keys( get_registered_nav_menus() ) as $location ) {
|
||||
unregister_nav_menu( $location );
|
||||
}
|
||||
|
||||
$orig_args = array(
|
||||
'name' => 'Original Name',
|
||||
'description' => 'Original Description',
|
||||
'slug' => 'original-slug',
|
||||
'taxonomy' => 'nav_menu',
|
||||
);
|
||||
|
||||
$this->menu_id = $this->factory->term->create( $orig_args );
|
||||
|
||||
register_meta(
|
||||
'term',
|
||||
'test_single_menu',
|
||||
array(
|
||||
'object_subtype' => self::TAXONOMY,
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register nav menu locations.
|
||||
*
|
||||
* @param array $locations Location slugs.
|
||||
*/
|
||||
public function register_nav_menu_locations( $locations ) {
|
||||
foreach ( $locations as $location ) {
|
||||
register_nav_menu( $location, ucfirst( $location ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::register_routes
|
||||
*/
|
||||
public function test_register_routes() {
|
||||
$routes = rest_get_server()->get_routes();
|
||||
$this->assertArrayHasKey( '/wp/v2/menus', $routes );
|
||||
$this->assertArrayHasKey( '/wp/v2/menus/(?P<id>[\d]+)', $routes );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_context_param
|
||||
*/
|
||||
public function test_context_param() {
|
||||
// Collection.
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menus' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
|
||||
$this->assertSameSets( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );
|
||||
$this->assertSame( array( 'v1' => true ), $data['endpoints'][0]['allow_batch'] );
|
||||
// Single.
|
||||
$tag1 = $this->factory->tag->create( array( 'name' => 'Season 5' ) );
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menus/' . $tag1 );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
|
||||
$this->assertSameSets( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );
|
||||
$this->assertSame( array( 'v1' => true ), $data['endpoints'][0]['allow_batch'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_collection_params
|
||||
*/
|
||||
public function test_registered_query_params() {
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menus' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$keys = array_keys( $data['endpoints'][0]['args'] );
|
||||
sort( $keys );
|
||||
$this->assertSame(
|
||||
array(
|
||||
'context',
|
||||
'exclude',
|
||||
'hide_empty',
|
||||
'include',
|
||||
'offset',
|
||||
'order',
|
||||
'orderby',
|
||||
'page',
|
||||
'per_page',
|
||||
'post',
|
||||
'search',
|
||||
'slug',
|
||||
),
|
||||
$keys
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_items
|
||||
*/
|
||||
public function test_get_items() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
wp_update_nav_menu_object(
|
||||
0,
|
||||
array(
|
||||
'description' => 'Test get',
|
||||
'menu-name' => 'test Name get',
|
||||
)
|
||||
);
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus' );
|
||||
$request->set_param( 'per_page', self::$per_page );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->check_get_taxonomy_terms_response( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item
|
||||
*/
|
||||
public function test_get_item() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$nav_menu_id = wp_update_nav_menu_object(
|
||||
0,
|
||||
array(
|
||||
'description' => 'Test menu',
|
||||
'menu-name' => 'test Name',
|
||||
)
|
||||
);
|
||||
|
||||
$this->register_nav_menu_locations( array( 'primary' ) );
|
||||
set_theme_mod( 'nav_menu_locations', array( 'primary' => $nav_menu_id ) );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus/' . $nav_menu_id );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->check_get_taxonomy_term_response( $response, $nav_menu_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::create_item
|
||||
*/
|
||||
public function test_create_item() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus' );
|
||||
$request->set_param( 'name', 'My Awesome menus' );
|
||||
$request->set_param( 'description', 'This menu is so awesome.' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 201, $response->get_status() );
|
||||
$headers = $response->get_headers();
|
||||
$data = $response->get_data();
|
||||
$this->assertStringContainsString( '/wp/v2/menus/' . $data['id'], $headers['Location'] );
|
||||
$this->assertSame( 'My Awesome menus', $data['name'] );
|
||||
$this->assertSame( 'This menu is so awesome.', $data['description'] );
|
||||
$this->assertSame( 'my-awesome-menus', $data['slug'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::create_item
|
||||
*/
|
||||
public function test_create_item_same_name() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
wp_update_nav_menu_object(
|
||||
0,
|
||||
array(
|
||||
'description' => 'This menu is so Original',
|
||||
'menu-name' => 'Original',
|
||||
)
|
||||
);
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus' );
|
||||
$request->set_param( 'name', 'Original' );
|
||||
$request->set_param( 'description', 'This menu is so Original' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertErrorResponse( 'menu_exists', $response, 400 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::update_item
|
||||
* @covers ::handle_auto_add
|
||||
*/
|
||||
public function test_update_item() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus/' . $this->menu_id );
|
||||
$request->set_param( 'name', 'New Name' );
|
||||
$request->set_param( 'description', 'New Description' );
|
||||
$request->set_param( 'auto_add', true );
|
||||
$request->set_param(
|
||||
'meta',
|
||||
array(
|
||||
'test_single_menu' => 'just meta',
|
||||
)
|
||||
);
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 200, $response->get_status() );
|
||||
$data = $response->get_data();
|
||||
$this->assertSame( 'New Name', $data['name'] );
|
||||
$this->assertSame( 'New Description', $data['description'] );
|
||||
$this->assertSame( true, $data['auto_add'] );
|
||||
$this->assertSame( 'new-name', $data['slug'] );
|
||||
$this->assertSame( 'just meta', $data['meta']['test_single_menu'] );
|
||||
$this->assertFalse( isset( $data['meta']['test_cat_meta'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::delete_item
|
||||
*/
|
||||
public function test_delete_item() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
$nav_menu_id = wp_update_nav_menu_object(
|
||||
0,
|
||||
array(
|
||||
'description' => 'Deleted Menu',
|
||||
'menu-name' => 'Deleted Menu',
|
||||
)
|
||||
);
|
||||
|
||||
$term = get_term_by( 'id', $nav_menu_id, self::TAXONOMY );
|
||||
|
||||
$request = new WP_REST_Request( 'DELETE', '/wp/v2/menus/' . $term->term_id );
|
||||
$request->set_param( 'force', true );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 200, $response->get_status() );
|
||||
$data = $response->get_data();
|
||||
$this->assertTrue( $data['deleted'] );
|
||||
$this->assertSame( 'Deleted Menu', $data['previous']['name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::prepare_item_for_response
|
||||
* @covers ::get_item
|
||||
*/
|
||||
public function test_prepare_item() {
|
||||
$nav_menu_id = wp_update_nav_menu_object(
|
||||
0,
|
||||
array(
|
||||
'description' => 'Foo Menu',
|
||||
'menu-name' => 'Foo Menu',
|
||||
)
|
||||
);
|
||||
|
||||
$term = get_term_by( 'id', $nav_menu_id, self::TAXONOMY );
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus/' . $term->term_id );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->check_taxonomy_term( $term, $data, $response->get_links() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item_schema
|
||||
*/
|
||||
public function test_get_item_schema() {
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/menus' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertSame( 7, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'id', $properties );
|
||||
$this->assertArrayHasKey( 'description', $properties );
|
||||
$this->assertArrayHasKey( 'meta', $properties );
|
||||
$this->assertArrayHasKey( 'name', $properties );
|
||||
$this->assertArrayHasKey( 'slug', $properties );
|
||||
$this->assertArrayHasKey( 'locations', $properties );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::create_item
|
||||
*/
|
||||
public function test_create_item_with_location_permission_correct() {
|
||||
$this->register_nav_menu_locations( array( 'primary', 'secondary' ) );
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus' );
|
||||
$request->set_param( 'name', 'My Awesome Term' );
|
||||
$request->set_param( 'slug', 'so-awesome' );
|
||||
$request->set_param( 'locations', 'primary' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 201, $response->get_status() );
|
||||
$data = $response->get_data();
|
||||
$term_id = $data['id'];
|
||||
$locations = get_nav_menu_locations();
|
||||
$this->assertSame( $locations['primary'], $term_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::create_item
|
||||
*/
|
||||
public function test_create_item_with_invalid_location() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus' );
|
||||
$request->set_param( 'name', 'My Awesome Term' );
|
||||
$request->set_param( 'slug', 'so-awesome' );
|
||||
$request->set_param( 'locations', 'bar' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 400, $response->get_status() );
|
||||
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||
$this->assertArrayHasKey( 'locations', $response->get_data()['data']['details'] );
|
||||
$this->assertSame( 'rest_invalid_menu_location', $response->get_data()['data']['details']['locations']['code'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::update_item
|
||||
*/
|
||||
public function test_update_item_with_no_location() {
|
||||
$this->register_nav_menu_locations( array( 'primary', 'secondary' ) );
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus/' . $this->menu_id );
|
||||
$request->set_param( 'name', 'New Name' );
|
||||
$request->set_param( 'description', 'New Description' );
|
||||
$request->set_param( 'slug', 'new-slug' );
|
||||
$request->set_param( 'locations', 'bar' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 400, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::update_item
|
||||
*/
|
||||
public function test_update_item_with_location_permission_correct() {
|
||||
$this->register_nav_menu_locations( array( 'primary', 'secondary' ) );
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus/' . $this->menu_id );
|
||||
$request->set_param( 'name', 'New Name' );
|
||||
$request->set_param( 'description', 'New Description' );
|
||||
$request->set_param( 'slug', 'new-slug' );
|
||||
$request->set_param( 'locations', 'primary' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( 200, $response->get_status() );
|
||||
$locations = get_nav_menu_locations();
|
||||
$this->assertSame( $locations['primary'], $this->menu_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::update_item
|
||||
*/
|
||||
public function test_update_item_with_location_permission_incorrect() {
|
||||
$this->register_nav_menu_locations( array( 'primary', 'secondary' ) );
|
||||
wp_set_current_user( self::$subscriber_id );
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus/' . $this->menu_id );
|
||||
$request->set_param( 'name', 'New Name' );
|
||||
$request->set_param( 'description', 'New Description' );
|
||||
$request->set_param( 'slug', 'new-slug' );
|
||||
$request->set_param( 'locations', 'primary' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertSame( rest_authorization_required_code(), $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::prepare_links
|
||||
*/
|
||||
public function test_get_item_links() {
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
$nav_menu_id = wp_update_nav_menu_object(
|
||||
0,
|
||||
array(
|
||||
'description' => 'Foo Menu',
|
||||
'menu-name' => 'Foo Menu',
|
||||
)
|
||||
);
|
||||
|
||||
register_nav_menu( 'foo', 'Bar' );
|
||||
|
||||
set_theme_mod( 'nav_menu_locations', array( 'foo' => $nav_menu_id ) );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/menus/%d', $nav_menu_id ) );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$links = $response->get_links();
|
||||
$this->assertArrayHasKey( 'https://api.w.org/menu-location', $links );
|
||||
|
||||
$location_url = rest_url( '/wp/v2/menu-locations/foo' );
|
||||
$this->assertSame( $location_url, $links['https://api.w.org/menu-location'][0]['href'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::update_item
|
||||
* @covers ::handle_locations
|
||||
*/
|
||||
public function test_change_menu_location() {
|
||||
$this->register_nav_menu_locations( array( 'primary', 'secondary' ) );
|
||||
$secondary_id = self::factory()->term->create(
|
||||
array(
|
||||
'name' => 'Secondary Name',
|
||||
'description' => 'Secondary Description',
|
||||
'slug' => 'secondary-slug',
|
||||
'taxonomy' => 'nav_menu',
|
||||
)
|
||||
);
|
||||
|
||||
$locations = get_nav_menu_locations();
|
||||
$locations['primary'] = $this->menu_id;
|
||||
$locations['secondary'] = $secondary_id;
|
||||
set_theme_mod( 'nav_menu_locations', $locations );
|
||||
|
||||
wp_set_current_user( self::$admin_id );
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/menus/' . $this->menu_id );
|
||||
$request->set_body_params(
|
||||
array(
|
||||
'locations' => array( 'secondary' ),
|
||||
)
|
||||
);
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertSame( 200, $response->get_status() );
|
||||
|
||||
$locations = get_nav_menu_locations();
|
||||
$this->assertArrayNotHasKey( 'primary', $locations );
|
||||
$this->assertArrayHasKey( 'secondary', $locations );
|
||||
$this->assertSame( $this->menu_id, $locations['secondary'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_items
|
||||
* @covers ::get_items_permissions_check
|
||||
*/
|
||||
public function test_get_items_no_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertErrorResponse( 'rest_cannot_view', $response, 401 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_items
|
||||
* @covers ::get_items_permissions_check
|
||||
*/
|
||||
public function test_get_item_no_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus/' . $this->menu_id );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertErrorResponse( 'rest_cannot_view', $response, 401 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_items
|
||||
* @covers ::get_items_permissions_check
|
||||
*/
|
||||
public function test_get_items_wrong_permission() {
|
||||
wp_set_current_user( self::$subscriber_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus' );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertErrorResponse( 'rest_cannot_view', $response, 403 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
* @covers ::get_item
|
||||
* @covers ::get_item_permissions_check
|
||||
*/
|
||||
public function test_get_item_wrong_permission() {
|
||||
wp_set_current_user( self::$subscriber_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/menus/' . $this->menu_id );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$this->assertErrorResponse( 'rest_cannot_view', $response, 403 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 40878
|
||||
*/
|
||||
public function test_it_allows_batch_requests_when_updating_menus() {
|
||||
$rest_server = rest_get_server();
|
||||
// This call is needed to initialize route_options.
|
||||
$rest_server->get_routes();
|
||||
$route_options = $rest_server->get_route_options( '/wp/v2/menus/(?P<id>[\d]+)' );
|
||||
|
||||
$this->assertArrayHasKey( 'allow_batch', $route_options );
|
||||
$this->assertSame( array( 'v1' => true ), $route_options['allow_batch'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Response $response Response Class.
|
||||
*/
|
||||
protected function check_get_taxonomy_terms_response( $response ) {
|
||||
$this->assertSame( 200, $response->get_status() );
|
||||
$data = $response->get_data();
|
||||
$args = array(
|
||||
'hide_empty' => false,
|
||||
);
|
||||
$tags = get_terms( self::TAXONOMY, $args );
|
||||
$this->assertSame( count( $tags ), count( $data ) );
|
||||
$this->assertSame( $tags[0]->term_id, $data[0]['id'] );
|
||||
$this->assertSame( $tags[0]->name, $data[0]['name'] );
|
||||
$this->assertSame( $tags[0]->slug, $data[0]['slug'] );
|
||||
$this->assertSame( $tags[0]->description, $data[0]['description'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Response $response Response Class.
|
||||
* @param int $id Term ID.
|
||||
*/
|
||||
protected function check_get_taxonomy_term_response( $response, $id ) {
|
||||
$this->assertSame( 200, $response->get_status() );
|
||||
|
||||
$data = $response->get_data();
|
||||
$menu = get_term( $id, self::TAXONOMY );
|
||||
$this->check_taxonomy_term( $menu, $data, $response->get_links() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_Term $term WP_Term object.
|
||||
* @param array $data Data from REST API.
|
||||
* @param array $links Array of links.
|
||||
*/
|
||||
protected function check_taxonomy_term( $term, $data, $links ) {
|
||||
$this->assertSame( $term->term_id, $data['id'] );
|
||||
$this->assertSame( $term->name, $data['name'] );
|
||||
$this->assertSame( $term->slug, $data['slug'] );
|
||||
$this->assertSame( $term->description, $data['description'] );
|
||||
$this->assertFalse( isset( $data['parent'] ) );
|
||||
|
||||
$locations = get_nav_menu_locations();
|
||||
if ( ! empty( $locations ) ) {
|
||||
$menu_locations = array();
|
||||
foreach ( $locations as $location => $menu_id ) {
|
||||
if ( $menu_id === $term->term_id ) {
|
||||
$menu_locations[] = $location;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertSame( $menu_locations, $data['locations'] );
|
||||
}
|
||||
|
||||
$relations = array(
|
||||
'self',
|
||||
'collection',
|
||||
'about',
|
||||
'https://api.w.org/post_type',
|
||||
);
|
||||
|
||||
if ( ! empty( $data['parent'] ) ) {
|
||||
$relations[] = 'up';
|
||||
}
|
||||
|
||||
if ( ! empty( $data['locations'] ) ) {
|
||||
$relations[] = 'https://api.w.org/menu-location';
|
||||
}
|
||||
|
||||
$this->assertSameSets( $relations, array_keys( $links ) );
|
||||
$this->assertStringContainsString( 'wp/v2/taxonomies/' . $term->taxonomy, $links['about'][0]['href'] );
|
||||
$this->assertSame( add_query_arg( 'menus', $term->term_id, rest_url( 'wp/v2/menu-items' ) ), $links['https://api.w.org/post_type'][0]['href'] );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user