rest-post-types-controller.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. /**
  3. * Unit tests covering WP_REST_Posts_Types_Controller functionality.
  4. *
  5. * @package WordPress
  6. * @subpackage REST API
  7. */
  8. /**
  9. * @group restapi
  10. */
  11. class WP_Test_REST_Post_Types_Controller extends WP_Test_REST_Controller_Testcase {
  12. public function test_register_routes() {
  13. $routes = rest_get_server()->get_routes();
  14. $this->assertArrayHasKey( '/wp/v2/types', $routes );
  15. $this->assertArrayHasKey( '/wp/v2/types/(?P<type>[\w-]+)', $routes );
  16. }
  17. public function test_context_param() {
  18. // Collection.
  19. $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/types' );
  20. $response = rest_get_server()->dispatch( $request );
  21. $data = $response->get_data();
  22. $this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
  23. $this->assertSameSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] );
  24. // Single.
  25. $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/types/post' );
  26. $response = rest_get_server()->dispatch( $request );
  27. $data = $response->get_data();
  28. $this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] );
  29. $this->assertSameSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] );
  30. }
  31. public function test_get_items() {
  32. $request = new WP_REST_Request( 'GET', '/wp/v2/types' );
  33. $response = rest_get_server()->dispatch( $request );
  34. $data = $response->get_data();
  35. $post_types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
  36. $this->assertSame( count( $post_types ), count( $data ) );
  37. $this->assertSame( $post_types['post']->name, $data['post']['slug'] );
  38. $this->check_post_type_obj( 'view', $post_types['post'], $data['post'], $data['post']['_links'] );
  39. $this->assertSame( $post_types['page']->name, $data['page']['slug'] );
  40. $this->check_post_type_obj( 'view', $post_types['page'], $data['page'], $data['page']['_links'] );
  41. $this->assertFalse( isset( $data['revision'] ) );
  42. }
  43. public function test_get_items_invalid_permission_for_context() {
  44. wp_set_current_user( 0 );
  45. $request = new WP_REST_Request( 'GET', '/wp/v2/types' );
  46. $request->set_param( 'context', 'edit' );
  47. $response = rest_get_server()->dispatch( $request );
  48. $this->assertErrorResponse( 'rest_cannot_view', $response, 401 );
  49. }
  50. public function test_get_item() {
  51. $request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
  52. $response = rest_get_server()->dispatch( $request );
  53. $this->check_post_type_object_response( 'view', $response );
  54. $data = $response->get_data();
  55. $this->assertSame( array( 'category', 'post_tag' ), $data['taxonomies'] );
  56. }
  57. public function test_get_item_page() {
  58. $request = new WP_REST_Request( 'GET', '/wp/v2/types/page' );
  59. $response = rest_get_server()->dispatch( $request );
  60. $this->check_post_type_object_response( 'view', $response, 'page' );
  61. $data = $response->get_data();
  62. $this->assertSame( array(), $data['taxonomies'] );
  63. }
  64. public function test_get_item_invalid_type() {
  65. $request = new WP_REST_Request( 'GET', '/wp/v2/types/invalid' );
  66. $response = rest_get_server()->dispatch( $request );
  67. $this->assertErrorResponse( 'rest_type_invalid', $response, 404 );
  68. }
  69. public function test_get_item_edit_context() {
  70. $editor_id = $this->factory->user->create( array( 'role' => 'editor' ) );
  71. wp_set_current_user( $editor_id );
  72. $request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
  73. $request->set_param( 'context', 'edit' );
  74. $response = rest_get_server()->dispatch( $request );
  75. $this->check_post_type_object_response( 'edit', $response );
  76. }
  77. public function test_get_item_invalid_permission_for_context() {
  78. wp_set_current_user( 0 );
  79. $request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
  80. $request->set_param( 'context', 'edit' );
  81. $response = rest_get_server()->dispatch( $request );
  82. $this->assertErrorResponse( 'rest_forbidden_context', $response, 401 );
  83. }
  84. public function test_create_item() {
  85. /** Post types can't be created */
  86. $request = new WP_REST_Request( 'POST', '/wp/v2/types' );
  87. $response = rest_get_server()->dispatch( $request );
  88. $this->assertSame( 404, $response->get_status() );
  89. }
  90. public function test_update_item() {
  91. /** Post types can't be updated */
  92. $request = new WP_REST_Request( 'POST', '/wp/v2/types/post' );
  93. $response = rest_get_server()->dispatch( $request );
  94. $this->assertSame( 404, $response->get_status() );
  95. }
  96. public function test_delete_item() {
  97. /** Post types can't be deleted */
  98. $request = new WP_REST_Request( 'DELETE', '/wp/v2/types/post' );
  99. $response = rest_get_server()->dispatch( $request );
  100. $this->assertSame( 404, $response->get_status() );
  101. }
  102. public function test_prepare_item() {
  103. $obj = get_post_type_object( 'post' );
  104. $endpoint = new WP_REST_Post_Types_Controller;
  105. $request = new WP_REST_Request;
  106. $request->set_param( 'context', 'edit' );
  107. $response = $endpoint->prepare_item_for_response( $obj, $request );
  108. $this->check_post_type_obj( 'edit', $obj, $response->get_data(), $response->get_links() );
  109. }
  110. public function test_prepare_item_limit_fields() {
  111. $obj = get_post_type_object( 'post' );
  112. $request = new WP_REST_Request;
  113. $endpoint = new WP_REST_Post_Types_Controller;
  114. $request->set_param( 'context', 'edit' );
  115. $request->set_param( '_fields', 'id,name' );
  116. $response = $endpoint->prepare_item_for_response( $obj, $request );
  117. $this->assertSame(
  118. array(
  119. // 'id' doesn't exist in this context.
  120. 'name',
  121. ),
  122. array_keys( $response->get_data() )
  123. );
  124. }
  125. public function test_get_item_schema() {
  126. $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/types' );
  127. $response = rest_get_server()->dispatch( $request );
  128. $data = $response->get_data();
  129. $properties = $data['schema']['properties'];
  130. $this->assertSame( 10, count( $properties ) );
  131. $this->assertArrayHasKey( 'capabilities', $properties );
  132. $this->assertArrayHasKey( 'description', $properties );
  133. $this->assertArrayHasKey( 'hierarchical', $properties );
  134. $this->assertArrayHasKey( 'viewable', $properties );
  135. $this->assertArrayHasKey( 'labels', $properties );
  136. $this->assertArrayHasKey( 'name', $properties );
  137. $this->assertArrayHasKey( 'slug', $properties );
  138. $this->assertArrayHasKey( 'supports', $properties );
  139. $this->assertArrayHasKey( 'taxonomies', $properties );
  140. $this->assertArrayHasKey( 'rest_base', $properties );
  141. }
  142. public function test_get_additional_field_registration() {
  143. $schema = array(
  144. 'type' => 'integer',
  145. 'description' => 'Some integer of mine',
  146. 'enum' => array( 1, 2, 3, 4 ),
  147. 'context' => array( 'view', 'edit' ),
  148. );
  149. register_rest_field(
  150. 'type',
  151. 'my_custom_int',
  152. array(
  153. 'schema' => $schema,
  154. 'get_callback' => array( $this, 'additional_field_get_callback' ),
  155. 'update_callback' => array( $this, 'additional_field_update_callback' ),
  156. )
  157. );
  158. $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/types/schema' );
  159. $response = rest_get_server()->dispatch( $request );
  160. $data = $response->get_data();
  161. $this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] );
  162. $this->assertSame( $schema, $data['schema']['properties']['my_custom_int'] );
  163. $request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
  164. $response = rest_get_server()->dispatch( $request );
  165. $this->assertArrayHasKey( 'my_custom_int', $response->data );
  166. global $wp_rest_additional_fields;
  167. $wp_rest_additional_fields = array();
  168. }
  169. public function additional_field_get_callback( $object ) {
  170. return 123;
  171. }
  172. protected function check_post_type_obj( $context, $post_type_obj, $data, $links ) {
  173. $this->assertSame( $post_type_obj->label, $data['name'] );
  174. $this->assertSame( $post_type_obj->name, $data['slug'] );
  175. $this->assertSame( $post_type_obj->description, $data['description'] );
  176. $this->assertSame( $post_type_obj->hierarchical, $data['hierarchical'] );
  177. $this->assertSame( $post_type_obj->rest_base, $data['rest_base'] );
  178. $links = test_rest_expand_compact_links( $links );
  179. $this->assertSame( rest_url( 'wp/v2/types' ), $links['collection'][0]['href'] );
  180. $this->assertArrayHasKey( 'https://api.w.org/items', $links );
  181. if ( 'edit' === $context ) {
  182. $this->assertSame( $post_type_obj->cap, $data['capabilities'] );
  183. $this->assertSame( $post_type_obj->labels, $data['labels'] );
  184. if ( in_array( $post_type_obj->name, array( 'post', 'page' ), true ) ) {
  185. $viewable = true;
  186. } else {
  187. $viewable = is_post_type_viewable( $post_type_obj );
  188. }
  189. $this->assertSame( $viewable, $data['viewable'] );
  190. $this->assertSame( get_all_post_type_supports( $post_type_obj->name ), $data['supports'] );
  191. } else {
  192. $this->assertFalse( isset( $data['capabilities'] ) );
  193. $this->assertFalse( isset( $data['viewable'] ) );
  194. $this->assertFalse( isset( $data['labels'] ) );
  195. $this->assertFalse( isset( $data['supports'] ) );
  196. }
  197. }
  198. protected function check_post_type_object_response( $context, $response, $post_type = 'post' ) {
  199. $this->assertSame( 200, $response->get_status() );
  200. $data = $response->get_data();
  201. $obj = get_post_type_object( $post_type );
  202. $this->check_post_type_obj( $context, $obj, $data, $response->get_links() );
  203. }
  204. }