/tests/phpunit/tests/post/meta.php

https://github.com/WordPress/wordpress-develop · PHP · 349 lines · 215 code · 76 blank · 58 comment · 0 complexity · 9c87c702cb5af978e09af8f6ccd7ce2c MD5 · raw file

  1. <?php
  2. /**
  3. * @group post
  4. * @group meta
  5. */
  6. class Tests_Post_Meta extends WP_UnitTestCase {
  7. private $last_register_meta_call = array(
  8. 'object_type' => '',
  9. 'meta_key' => '',
  10. 'args' => array(),
  11. );
  12. protected static $author;
  13. protected static $post_id;
  14. protected static $post_id_2;
  15. public static function wpSetUpBeforeClass( $factory ) {
  16. self::$author = $factory->user->create_and_get( array( 'role' => 'editor' ) );
  17. self::$post_id = $factory->post->create(
  18. array(
  19. 'post_author' => self::$author->ID,
  20. 'post_status' => 'publish',
  21. 'post_content' => rand_str(),
  22. 'post_title' => rand_str(),
  23. )
  24. );
  25. self::$post_id_2 = $factory->post->create(
  26. array(
  27. 'post_author' => self::$author->ID,
  28. 'post_status' => 'publish',
  29. 'post_content' => rand_str(),
  30. 'post_title' => rand_str(),
  31. )
  32. );
  33. }
  34. public static function wpTearDownAfterClass() {
  35. wp_delete_post( self::$post_id, true );
  36. wp_delete_post( self::$post_id_2, true );
  37. self::delete_user( self::$author );
  38. }
  39. function test_unique_postmeta() {
  40. // Add a unique post meta item.
  41. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'unique', 'value', true ) );
  42. // Check unique is enforced.
  43. $this->assertFalse( add_post_meta( self::$post_id, 'unique', 'another value', true ) );
  44. // Check it exists.
  45. $this->assertSame( 'value', get_post_meta( self::$post_id, 'unique', true ) );
  46. $this->assertSame( array( 'value' ), get_post_meta( self::$post_id, 'unique', false ) );
  47. // Fail to delete the wrong value.
  48. $this->assertFalse( delete_post_meta( self::$post_id, 'unique', 'wrong value' ) );
  49. // Delete it.
  50. $this->assertTrue( delete_post_meta( self::$post_id, 'unique', 'value' ) );
  51. // Check it is deleted.
  52. $this->assertSame( '', get_post_meta( self::$post_id, 'unique', true ) );
  53. $this->assertSame( array(), get_post_meta( self::$post_id, 'unique', false ) );
  54. }
  55. function test_nonunique_postmeta() {
  56. // Add two non-unique post meta items.
  57. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'nonunique', 'value' ) );
  58. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'nonunique', 'another value' ) );
  59. // Check they exist.
  60. $this->assertSame( 'value', get_post_meta( self::$post_id, 'nonunique', true ) );
  61. $this->assertSame( array( 'value', 'another value' ), get_post_meta( self::$post_id, 'nonunique', false ) );
  62. // Fail to delete the wrong value.
  63. $this->assertFalse( delete_post_meta( self::$post_id, 'nonunique', 'wrong value' ) );
  64. // Delete the first one.
  65. $this->assertTrue( delete_post_meta( self::$post_id, 'nonunique', 'value' ) );
  66. // Check the remainder exists.
  67. $this->assertSame( 'another value', get_post_meta( self::$post_id, 'nonunique', true ) );
  68. $this->assertSame( array( 'another value' ), get_post_meta( self::$post_id, 'nonunique', false ) );
  69. // Add a third one.
  70. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'nonunique', 'someother value' ) );
  71. // Check they exist.
  72. $expected = array(
  73. 'someother value',
  74. 'another value',
  75. );
  76. sort( $expected );
  77. $this->assertTrue( in_array( get_post_meta( self::$post_id, 'nonunique', true ), $expected, true ) );
  78. $actual = get_post_meta( self::$post_id, 'nonunique', false );
  79. sort( $actual );
  80. $this->assertSame( $expected, $actual );
  81. // Delete the lot.
  82. $this->assertTrue( delete_post_meta_by_key( 'nonunique' ) );
  83. }
  84. function test_update_post_meta() {
  85. // Add a unique post meta item.
  86. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'unique_update', 'value', true ) );
  87. // Add two non-unique post meta items.
  88. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'nonunique_update', 'value' ) );
  89. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'nonunique_update', 'another value' ) );
  90. // Check they exist.
  91. $this->assertSame( 'value', get_post_meta( self::$post_id, 'unique_update', true ) );
  92. $this->assertSame( array( 'value' ), get_post_meta( self::$post_id, 'unique_update', false ) );
  93. $this->assertSame( 'value', get_post_meta( self::$post_id, 'nonunique_update', true ) );
  94. $this->assertSame( array( 'value', 'another value' ), get_post_meta( self::$post_id, 'nonunique_update', false ) );
  95. // Update them.
  96. $this->assertTrue( update_post_meta( self::$post_id, 'unique_update', 'new', 'value' ) );
  97. $this->assertTrue( update_post_meta( self::$post_id, 'nonunique_update', 'new', 'value' ) );
  98. $this->assertTrue( update_post_meta( self::$post_id, 'nonunique_update', 'another new', 'another value' ) );
  99. // Check they updated.
  100. $this->assertSame( 'new', get_post_meta( self::$post_id, 'unique_update', true ) );
  101. $this->assertSame( array( 'new' ), get_post_meta( self::$post_id, 'unique_update', false ) );
  102. $this->assertSame( 'new', get_post_meta( self::$post_id, 'nonunique_update', true ) );
  103. $this->assertSame( array( 'new', 'another new' ), get_post_meta( self::$post_id, 'nonunique_update', false ) );
  104. }
  105. function test_delete_post_meta() {
  106. // Add two unique post meta items.
  107. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'unique_delete', 'value', true ) );
  108. $this->assertInternalType( 'integer', add_post_meta( self::$post_id_2, 'unique_delete', 'value', true ) );
  109. // Check they exist.
  110. $this->assertSame( 'value', get_post_meta( self::$post_id, 'unique_delete', true ) );
  111. $this->assertSame( 'value', get_post_meta( self::$post_id_2, 'unique_delete', true ) );
  112. // Delete one of them.
  113. $this->assertTrue( delete_post_meta( self::$post_id, 'unique_delete', 'value' ) );
  114. // Check the other still exists.
  115. $this->assertSame( 'value', get_post_meta( self::$post_id_2, 'unique_delete', true ) );
  116. }
  117. function test_delete_post_meta_by_key() {
  118. // Add two unique post meta items.
  119. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'unique_delete_by_key', 'value', true ) );
  120. $this->assertInternalType( 'integer', add_post_meta( self::$post_id_2, 'unique_delete_by_key', 'value', true ) );
  121. // Check they exist.
  122. $this->assertSame( 'value', get_post_meta( self::$post_id, 'unique_delete_by_key', true ) );
  123. $this->assertSame( 'value', get_post_meta( self::$post_id_2, 'unique_delete_by_key', true ) );
  124. // Delete one of them.
  125. $this->assertTrue( delete_post_meta_by_key( 'unique_delete_by_key' ) );
  126. // Check the other still exists.
  127. $this->assertSame( '', get_post_meta( self::$post_id_2, 'unique_delete_by_key', true ) );
  128. $this->assertSame( '', get_post_meta( self::$post_id_2, 'unique_delete_by_key', true ) );
  129. }
  130. function test_get_post_meta_by_id() {
  131. $mid = add_post_meta( self::$post_id, 'get_post_meta_by_key', 'get_post_meta_by_key_value', true );
  132. $this->assertInternalType( 'integer', $mid );
  133. $mobj = new stdClass;
  134. $mobj->meta_id = $mid;
  135. $mobj->post_id = self::$post_id;
  136. $mobj->meta_key = 'get_post_meta_by_key';
  137. $mobj->meta_value = 'get_post_meta_by_key_value';
  138. $this->assertEquals( $mobj, get_post_meta_by_id( $mid ) );
  139. delete_metadata_by_mid( 'post', $mid );
  140. $mid = add_post_meta( self::$post_id, 'get_post_meta_by_key', array( 'foo', 'bar' ), true );
  141. $this->assertInternalType( 'integer', $mid );
  142. $mobj->meta_id = $mid;
  143. $mobj->meta_value = array( 'foo', 'bar' );
  144. $this->assertEquals( $mobj, get_post_meta_by_id( $mid ) );
  145. delete_metadata_by_mid( 'post', $mid );
  146. }
  147. function test_delete_meta() {
  148. $mid = add_post_meta( self::$post_id, 'delete_meta', 'delete_meta_value', true );
  149. $this->assertInternalType( 'integer', $mid );
  150. $this->assertTrue( delete_meta( $mid ) );
  151. $this->assertFalse( get_metadata_by_mid( 'post', $mid ) );
  152. $this->assertFalse( delete_meta( 123456789 ) );
  153. }
  154. function test_update_meta() {
  155. // Add a unique post meta item.
  156. $this->assertInternalType( 'integer', $mid1 = add_post_meta( self::$post_id, 'unique_update', 'value', true ) );
  157. // Add two non-unique post meta items.
  158. $this->assertInternalType( 'integer', $mid2 = add_post_meta( self::$post_id, 'nonunique_update', 'value' ) );
  159. $this->assertInternalType( 'integer', $mid3 = add_post_meta( self::$post_id, 'nonunique_update', 'another value' ) );
  160. // Check they exist.
  161. $this->assertSame( 'value', get_post_meta( self::$post_id, 'unique_update', true ) );
  162. $this->assertSame( array( 'value' ), get_post_meta( self::$post_id, 'unique_update', false ) );
  163. $this->assertSame( 'value', get_post_meta( self::$post_id, 'nonunique_update', true ) );
  164. $this->assertSame( array( 'value', 'another value' ), get_post_meta( self::$post_id, 'nonunique_update', false ) );
  165. // Update them.
  166. $this->assertTrue( update_meta( $mid1, 'unique_update', 'new' ) );
  167. $this->assertTrue( update_meta( $mid2, 'nonunique_update', 'new' ) );
  168. $this->assertTrue( update_meta( $mid3, 'nonunique_update', 'another new' ) );
  169. // Check they updated.
  170. $this->assertSame( 'new', get_post_meta( self::$post_id, 'unique_update', true ) );
  171. $this->assertSame( array( 'new' ), get_post_meta( self::$post_id, 'unique_update', false ) );
  172. $this->assertSame( 'new', get_post_meta( self::$post_id, 'nonunique_update', true ) );
  173. $this->assertSame( array( 'new', 'another new' ), get_post_meta( self::$post_id, 'nonunique_update', false ) );
  174. // Slashed update.
  175. $data = "'quote and \slash";
  176. $this->assertTrue( update_meta( $mid1, 'unique_update', addslashes( $data ) ) );
  177. $meta = get_metadata_by_mid( 'post', $mid1 );
  178. $this->assertSame( $data, $meta->meta_value );
  179. }
  180. /**
  181. * @ticket 12860
  182. */
  183. function test_funky_post_meta() {
  184. $classy = new StdClass();
  185. $classy->ID = 1;
  186. $classy->stringy = 'I love slashes\\\\';
  187. $funky_meta[] = $classy;
  188. $classy = new StdClass();
  189. $classy->ID = 2;
  190. $classy->stringy = 'I love slashes\\\\ more';
  191. $funky_meta[] = $classy;
  192. // Add a post meta item.
  193. $this->assertInternalType( 'integer', add_post_meta( self::$post_id, 'test_funky_post_meta', $funky_meta, true ) );
  194. // Check it exists.
  195. $this->assertEquals( $funky_meta, get_post_meta( self::$post_id, 'test_funky_post_meta', true ) );
  196. }
  197. /**
  198. * @ticket 38323
  199. * @dataProvider data_register_post_meta
  200. */
  201. public function test_register_post_meta( $post_type, $meta_key, $args ) {
  202. add_filter( 'register_meta_args', array( $this, 'filter_register_meta_args_set_last_register_meta_call' ), 10, 4 );
  203. register_post_meta( $post_type, $meta_key, $args );
  204. $args['object_subtype'] = $post_type;
  205. // Reset global so subsequent data tests do not get polluted.
  206. $GLOBALS['wp_meta_keys'] = array();
  207. $this->assertSame( 'post', $this->last_register_meta_call['object_type'] );
  208. $this->assertSame( $meta_key, $this->last_register_meta_call['meta_key'] );
  209. $this->assertSame( $args, $this->last_register_meta_call['args'] );
  210. }
  211. public function data_register_post_meta() {
  212. return array(
  213. array( 'post', 'registered_key1', array( 'single' => true ) ),
  214. array( 'page', 'registered_key2', array() ),
  215. array( '', 'registered_key3', array( 'sanitize_callback' => 'absint' ) ),
  216. );
  217. }
  218. public function filter_register_meta_args_set_last_register_meta_call( $args, $defaults, $object_type, $meta_key ) {
  219. $this->last_register_meta_call['object_type'] = $object_type;
  220. $this->last_register_meta_call['meta_key'] = $meta_key;
  221. $this->last_register_meta_call['args'] = $args;
  222. return $args;
  223. }
  224. /**
  225. * @ticket 38323
  226. * @dataProvider data_unregister_post_meta
  227. */
  228. public function test_unregister_post_meta( $post_type, $meta_key ) {
  229. global $wp_meta_keys;
  230. register_post_meta( $post_type, $meta_key, array() );
  231. unregister_post_meta( $post_type, $meta_key );
  232. $actual = $wp_meta_keys;
  233. // Reset global so subsequent data tests do not get polluted.
  234. $wp_meta_keys = array();
  235. $this->assertEmpty( $actual );
  236. }
  237. public function data_unregister_post_meta() {
  238. return array(
  239. array( 'post', 'registered_key1' ),
  240. array( 'page', 'registered_key2' ),
  241. array( '', 'registered_key3' ),
  242. );
  243. }
  244. /**
  245. * @ticket 44467
  246. */
  247. public function test_add_metadata_sets_posts_last_changed() {
  248. $post_id = self::factory()->post->create();
  249. wp_cache_delete( 'last_changed', 'posts' );
  250. $this->assertInternalType( 'integer', add_metadata( 'post', $post_id, 'foo', 'bar' ) );
  251. $this->assertNotFalse( wp_cache_get_last_changed( 'posts' ) );
  252. }
  253. /**
  254. * @ticket 44467
  255. */
  256. public function test_update_metadata_sets_posts_last_changed() {
  257. $post_id = self::factory()->post->create();
  258. wp_cache_delete( 'last_changed', 'posts' );
  259. $this->assertInternalType( 'integer', update_metadata( 'post', $post_id, 'foo', 'bar' ) );
  260. $this->assertNotFalse( wp_cache_get_last_changed( 'posts' ) );
  261. }
  262. /**
  263. * @ticket 44467
  264. */
  265. public function test_delete_metadata_sets_posts_last_changed() {
  266. $post_id = self::factory()->post->create();
  267. update_metadata( 'post', $post_id, 'foo', 'bar' );
  268. wp_cache_delete( 'last_changed', 'posts' );
  269. $this->assertTrue( delete_metadata( 'post', $post_id, 'foo' ) );
  270. $this->assertNotFalse( wp_cache_get_last_changed( 'posts' ) );
  271. }
  272. }