mapMetaCap.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <?php
  2. /**
  3. * @group user
  4. * @group capabilities
  5. */
  6. class Tests_User_MapMetaCap extends WP_UnitTestCase {
  7. protected static $post_type = 'mapmetacap';
  8. protected static $super_admins = null;
  9. protected static $user_id = null;
  10. protected static $author_id = null;
  11. protected static $post_id = null;
  12. public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
  13. self::$user_id = $factory->user->create( array( 'role' => 'administrator' ) );
  14. self::$author_id = $factory->user->create( array( 'role' => 'administrator' ) );
  15. if ( isset( $GLOBALS['super_admins'] ) ) {
  16. self::$super_admins = $GLOBALS['super_admins'];
  17. }
  18. $user = new WP_User( self::$user_id );
  19. $GLOBALS['super_admins'] = array( $user->user_login );
  20. register_post_type( self::$post_type );
  21. self::$post_id = $factory->post->create(
  22. array(
  23. 'post_type' => self::$post_type,
  24. 'post_status' => 'private',
  25. 'post_author' => self::$author_id,
  26. )
  27. );
  28. }
  29. public static function wpTearDownAfterClass() {
  30. $GLOBALS['super_admins'] = self::$super_admins;
  31. unset( $GLOBALS['wp_post_types'][ self::$post_type ] );
  32. }
  33. /**
  34. * @ticket 13905
  35. */
  36. function test_capability_type_post_with_invalid_id() {
  37. $this->assertSame(
  38. array( 'do_not_allow' ),
  39. map_meta_cap( 'edit_post', self::$user_id, self::$post_id + 1 )
  40. );
  41. }
  42. function test_capability_type_post_with_no_extra_caps() {
  43. register_post_type(
  44. self::$post_type,
  45. array(
  46. 'capability_type' => 'post',
  47. )
  48. );
  49. $post_type_object = get_post_type_object( self::$post_type );
  50. $this->assertTrue( $post_type_object->map_meta_cap );
  51. $this->assertSame(
  52. array( 'edit_others_posts', 'edit_private_posts' ),
  53. map_meta_cap( 'edit_post', self::$user_id, self::$post_id )
  54. );
  55. $this->assertSame(
  56. array( 'edit_others_posts', 'edit_private_posts' ),
  57. map_meta_cap( $post_type_object->cap->edit_post, self::$user_id, self::$post_id )
  58. );
  59. $this->assertSame(
  60. array( 'read_private_posts' ),
  61. map_meta_cap( 'read_post', self::$user_id, self::$post_id )
  62. );
  63. $this->assertSame(
  64. array( 'read_private_posts' ),
  65. map_meta_cap( $post_type_object->cap->read_post, self::$user_id, self::$post_id )
  66. );
  67. $this->assertSame(
  68. array( 'delete_others_posts', 'delete_private_posts' ),
  69. map_meta_cap( 'delete_post', self::$user_id, self::$post_id )
  70. );
  71. $this->assertSame(
  72. array( 'delete_others_posts', 'delete_private_posts' ),
  73. map_meta_cap( $post_type_object->cap->delete_post, self::$user_id, self::$post_id )
  74. );
  75. }
  76. function test_custom_capability_type_with_map_meta_cap() {
  77. register_post_type(
  78. self::$post_type,
  79. array(
  80. 'capability_type' => 'book',
  81. 'map_meta_cap' => true,
  82. )
  83. );
  84. $post_type_object = get_post_type_object( self::$post_type );
  85. $this->assertSame(
  86. array( 'edit_others_books', 'edit_private_books' ),
  87. map_meta_cap( 'edit_post', self::$user_id, self::$post_id )
  88. );
  89. $this->assertSame(
  90. array( 'edit_others_books', 'edit_private_books' ),
  91. map_meta_cap( $post_type_object->cap->edit_post, self::$user_id, self::$post_id )
  92. );
  93. $this->assertSame(
  94. array( 'read_private_books' ),
  95. map_meta_cap( 'read_post', self::$user_id, self::$post_id )
  96. );
  97. $this->assertSame(
  98. array( 'read_private_books' ),
  99. map_meta_cap( $post_type_object->cap->read_post, self::$user_id, self::$post_id )
  100. );
  101. $this->assertSame(
  102. array( 'delete_others_books', 'delete_private_books' ),
  103. map_meta_cap( 'delete_post', self::$user_id, self::$post_id )
  104. );
  105. $this->assertSame(
  106. array( 'delete_others_books', 'delete_private_books' ),
  107. map_meta_cap( $post_type_object->cap->delete_post, self::$user_id, self::$post_id )
  108. );
  109. }
  110. function test_capability_type_post_with_one_renamed_cap() {
  111. register_post_type(
  112. self::$post_type,
  113. array(
  114. 'capability_type' => 'post',
  115. 'capabilities' => array( 'edit_posts' => 'edit_books' ),
  116. )
  117. );
  118. $post_type_object = get_post_type_object( self::$post_type );
  119. $this->assertFalse( $post_type_object->map_meta_cap );
  120. $this->assertSame(
  121. array( 'edit_post' ),
  122. map_meta_cap( 'edit_post', self::$user_id, self::$post_id )
  123. );
  124. $this->assertSame(
  125. array( 'edit_post' ),
  126. map_meta_cap( $post_type_object->cap->edit_post, self::$user_id, self::$post_id )
  127. );
  128. $this->assertSame(
  129. array( 'read_post' ),
  130. map_meta_cap( 'read_post', self::$user_id, self::$post_id )
  131. );
  132. $this->assertSame(
  133. array( 'read_post' ),
  134. map_meta_cap( $post_type_object->cap->read_post, self::$user_id, self::$post_id )
  135. );
  136. $this->assertSame(
  137. array( 'delete_post' ),
  138. map_meta_cap( 'delete_post', self::$user_id, self::$post_id )
  139. );
  140. $this->assertSame(
  141. array( 'delete_post' ),
  142. map_meta_cap( $post_type_object->cap->delete_post, self::$user_id, self::$post_id )
  143. );
  144. }
  145. function test_capability_type_post_map_meta_cap_true_with_renamed_cap() {
  146. register_post_type(
  147. self::$post_type,
  148. array(
  149. 'capability_type' => 'post',
  150. 'map_meta_cap' => true,
  151. 'capabilities' => array(
  152. 'edit_post' => 'edit_book', // maps back to itself.
  153. 'edit_others_posts' => 'edit_others_books',
  154. ),
  155. )
  156. );
  157. $post_type_object = get_post_type_object( self::$post_type );
  158. $this->assertTrue( $post_type_object->map_meta_cap );
  159. $this->assertSame(
  160. array( 'edit_others_books', 'edit_private_posts' ),
  161. map_meta_cap( 'edit_post', self::$user_id, self::$post_id )
  162. );
  163. $this->assertSame(
  164. array( 'edit_others_books', 'edit_private_posts' ),
  165. map_meta_cap( $post_type_object->cap->edit_post, self::$user_id, self::$post_id )
  166. );
  167. $this->assertSame(
  168. array( 'read_private_posts' ),
  169. map_meta_cap( 'read_post', self::$user_id, self::$post_id )
  170. );
  171. $this->assertSame(
  172. array( 'read_private_posts' ),
  173. map_meta_cap( $post_type_object->cap->read_post, self::$user_id, self::$post_id )
  174. );
  175. $this->assertSame(
  176. array( 'delete_others_posts', 'delete_private_posts' ),
  177. map_meta_cap( 'delete_post', self::$user_id, self::$post_id )
  178. );
  179. $this->assertSame(
  180. array( 'delete_others_posts', 'delete_private_posts' ),
  181. map_meta_cap( $post_type_object->cap->delete_post, self::$user_id, self::$post_id )
  182. );
  183. }
  184. function test_capability_type_post_with_all_meta_caps_renamed() {
  185. register_post_type(
  186. self::$post_type,
  187. array(
  188. 'capability_type' => 'post',
  189. 'capabilities' => array(
  190. 'edit_post' => 'edit_book',
  191. 'read_post' => 'read_book',
  192. 'delete_post' => 'delete_book',
  193. ),
  194. )
  195. );
  196. $post_type_object = get_post_type_object( self::$post_type );
  197. $this->assertFalse( $post_type_object->map_meta_cap );
  198. $this->assertSame(
  199. array( 'edit_book' ),
  200. map_meta_cap( 'edit_post', self::$user_id, self::$post_id )
  201. );
  202. $this->assertSame(
  203. array( 'edit_book' ),
  204. map_meta_cap( $post_type_object->cap->edit_post, self::$user_id, self::$post_id )
  205. );
  206. $this->assertSame(
  207. array( 'read_book' ),
  208. map_meta_cap( 'read_post', self::$user_id, self::$post_id )
  209. );
  210. $this->assertSame(
  211. array( 'read_book' ),
  212. map_meta_cap( $post_type_object->cap->read_post, self::$user_id, self::$post_id )
  213. );
  214. $this->assertSame(
  215. array( 'delete_book' ),
  216. map_meta_cap( 'delete_post', self::$user_id, self::$post_id )
  217. );
  218. $this->assertSame(
  219. array( 'delete_book' ),
  220. map_meta_cap( $post_type_object->cap->delete_post, self::$user_id, self::$post_id )
  221. );
  222. }
  223. function test_capability_type_post_with_all_meta_caps_renamed_mapped() {
  224. register_post_type(
  225. self::$post_type,
  226. array(
  227. 'capability_type' => 'post',
  228. 'map_meta_cap' => true,
  229. 'capabilities' => array(
  230. 'edit_post' => 'edit_book',
  231. 'read_post' => 'read_book',
  232. 'delete_post' => 'delete_book',
  233. ),
  234. )
  235. );
  236. $post_type_object = get_post_type_object( self::$post_type );
  237. $this->assertTrue( $post_type_object->map_meta_cap );
  238. $this->assertSame(
  239. array( 'edit_others_posts', 'edit_private_posts' ),
  240. map_meta_cap( 'edit_post', self::$user_id, self::$post_id )
  241. );
  242. $this->assertSame(
  243. array( 'edit_others_posts', 'edit_private_posts' ),
  244. map_meta_cap( $post_type_object->cap->edit_post, self::$user_id, self::$post_id )
  245. );
  246. $this->assertSame(
  247. array( 'read_private_posts' ),
  248. map_meta_cap( 'read_post', self::$user_id, self::$post_id )
  249. );
  250. $this->assertSame(
  251. array( 'read_private_posts' ),
  252. map_meta_cap( $post_type_object->cap->read_post, self::$user_id, self::$post_id )
  253. );
  254. $this->assertSame(
  255. array( 'delete_others_posts', 'delete_private_posts' ),
  256. map_meta_cap( 'delete_post', self::$user_id, self::$post_id )
  257. );
  258. $this->assertSame(
  259. array( 'delete_others_posts', 'delete_private_posts' ),
  260. map_meta_cap( $post_type_object->cap->delete_post, self::$user_id, self::$post_id )
  261. );
  262. }
  263. /**
  264. * @ticket 30991
  265. */
  266. function test_delete_posts_cap_without_map_meta_cap() {
  267. register_post_type(
  268. self::$post_type,
  269. array(
  270. 'capability_type' => 'post',
  271. 'map_meta_cap' => false,
  272. )
  273. );
  274. $post_type_object = get_post_type_object( self::$post_type );
  275. $this->assertFalse( $post_type_object->map_meta_cap );
  276. $this->assertSame( 'delete_posts', $post_type_object->cap->delete_posts );
  277. }
  278. function test_unfiltered_html_cap() {
  279. if ( defined( 'DISALLOW_UNFILTERED_HTML' ) ) {
  280. $this->assertFalse( DISALLOW_UNFILTERED_HTML );
  281. }
  282. if ( is_multisite() ) {
  283. $this->assertSame( array( 'do_not_allow' ), map_meta_cap( 'unfiltered_html', 0 ) );
  284. $this->assertSame( array( 'unfiltered_html' ), map_meta_cap( 'unfiltered_html', self::$user_id ) );
  285. } else {
  286. $this->assertSame( array( 'unfiltered_html' ), map_meta_cap( 'unfiltered_html', self::$user_id ) );
  287. }
  288. }
  289. /**
  290. * @ticket 20488
  291. */
  292. function test_file_edit_caps_not_reliant_on_unfiltered_html_constant() {
  293. $this->assertFalse( defined( 'DISALLOW_FILE_MODS' ) );
  294. $this->assertFalse( defined( 'DISALLOW_FILE_EDIT' ) );
  295. if ( ! defined( 'DISALLOW_UNFILTERED_HTML' ) ) {
  296. define( 'DISALLOW_UNFILTERED_HTML', true );
  297. }
  298. $this->assertTrue( DISALLOW_UNFILTERED_HTML );
  299. $this->assertSame( array( 'update_core' ), map_meta_cap( 'update_core', self::$user_id ) );
  300. $this->assertSame( array( 'edit_plugins' ), map_meta_cap( 'edit_plugins', self::$user_id ) );
  301. }
  302. /**
  303. * Test a post without an author.
  304. *
  305. * @ticket 27020
  306. */
  307. function test_authorless_posts_capabilties() {
  308. $post_id = self::factory()->post->create(
  309. array(
  310. 'post_author' => 0,
  311. 'post_type' => 'post',
  312. 'post_status' => 'publish',
  313. )
  314. );
  315. $editor = self::factory()->user->create( array( 'role' => 'editor' ) );
  316. $this->assertSame( array( 'edit_others_posts', 'edit_published_posts' ), map_meta_cap( 'edit_post', $editor, $post_id ) );
  317. $this->assertSame( array( 'delete_others_posts', 'delete_published_posts' ), map_meta_cap( 'delete_post', $editor, $post_id ) );
  318. }
  319. /**
  320. * Test deleting front page.
  321. *
  322. * @ticket 37580
  323. */
  324. function test_only_users_who_can_manage_options_can_delete_page_on_front() {
  325. $post_id = self::factory()->post->create(
  326. array(
  327. 'post_type' => 'page',
  328. 'post_status' => 'publish',
  329. )
  330. );
  331. update_option( 'page_on_front', $post_id );
  332. $caps = map_meta_cap( 'delete_page', self::$user_id, $post_id );
  333. delete_option( 'page_on_front' );
  334. $this->assertSame( array( 'manage_options' ), $caps );
  335. }
  336. /**
  337. * Test deleting posts page.
  338. *
  339. * @ticket 37580
  340. */
  341. function test_only_users_who_can_manage_options_can_delete_page_for_posts() {
  342. $post_id = self::factory()->post->create(
  343. array(
  344. 'post_type' => 'page',
  345. 'post_status' => 'publish',
  346. )
  347. );
  348. update_option( 'page_for_posts', $post_id );
  349. $caps = map_meta_cap( 'delete_page', self::$user_id, $post_id );
  350. delete_option( 'page_for_posts' );
  351. $this->assertSame( array( 'manage_options' ), $caps );
  352. }
  353. }