assertSame( $stored, esc_textarea( ceo_meta_for_editor( $stored ) ) ); } /** And the value the author actually typed is what they see again. */ #[DataProvider( 'authoredTextProvider' )] public function testTheAuthorSeesWhatTheyTyped( $typed ) { $this->assertSame( $typed, ceo_meta_for_editor( esc_textarea( $typed ) ) ); } public static function authoredTextProvider() { return array( 'markup' => array( 'bold' ), 'an entity typed literally' => array( '<b>' ), 'a bare ampersand' => array( 'Tom & Jerry' ), 'quotes' => array( 'she said "hi"' ), 'an apostrophe' => array( "it's fine" ), 'a url with a query string' => array( 'https://x.test/?a=1&b=2' ), ); } /** * A raw value written past the meta boxes must not survive as live markup once the sink * escapes it. This is the Custom Fields path. */ public function testRawMarkupFromCustomFieldsBecomesInert() { $raw = ''; $out = esc_textarea( ceo_meta_for_editor( $raw ) ); $this->assertStringNotContainsString( '', $out ); $this->assertStringNotContainsString( 'assertSame( $expected, ceo_meta_for_editor( $stored ) ); } public static function decodingProvider() { return array( array( '<b>', '' ), array( '&amp;', '&' ), array( '"x"', '"x"' ), array( ''', "'" ), array( '', '' ), array( '¬anentity;', '¬anentity;' ), ); } #[DataProvider( 'nonStringProvider' )] public function testNonStringInputIsHandled( $input, $expected ) { $this->assertSame( $expected, ceo_meta_for_editor( $input ) ); } public static function nonStringProvider() { return array( array( null, '' ), array( false, '' ), array( 123, '123' ), ); } public function testSaveHandlerUnslashesEditorTextExactlyOnce() { $post = $this->setGlobalPost( 17 ); $this->grantCurrentUserCap( 'edit_post' ); CE_Test_State::$valid_nonces['admin-meta.php'] = 'valid-nonce'; $typed = "C:\\comics\\today's note"; $_POST = array( 'comic_nonce' => 'valid-nonce', 'transcript' => addslashes( $typed ), ); ceo_handle_edit_save_comic( 17, $post ); $this->assertSame( esc_textarea( $typed ), CE_Test_State::$post_meta['17:transcript'] ); unset( $_POST ); } public function testSaveHandlerRejectsAnInvalidNonce() { $post = $this->setGlobalPost( 17 ); $this->grantCurrentUserCap( 'edit_post' ); $_POST = array( 'comic_nonce' => 'invalid', 'transcript' => 'must not be saved', ); ceo_handle_edit_save_comic( 17, $post ); $this->assertArrayNotHasKey( '17:transcript', CE_Test_State::$post_meta ); unset( $_POST ); } /** * A meta row can exist while holding the empty string -- the Custom Fields panel, an * importer or wp-cli all leave one behind. get_post_meta() reports '' for that row and for * no row at all, so a save handler that branches on '' and reaches for a unique * add_post_meta() has its write refused and drops what the author typed. */ public function testSaveHandlerWritesOverAnExistingEmptyMetaRow() { $post = $this->setGlobalPost( 17 ); $this->grantCurrentUserCap( 'edit_post' ); CE_Test_State::$valid_nonces['admin-meta.php'] = 'valid-nonce'; $this->setPostMeta( 17, 'transcript', '' ); $_POST = array( 'comic_nonce' => 'valid-nonce', 'transcript' => 'the newly typed transcript', ); ceo_handle_edit_save_comic( 17, $post ); $this->assertSame( 'the newly typed transcript', CE_Test_State::$post_meta['17:transcript'] ); unset( $_POST ); } public function testSaveHandlerIgnoresArrayShapedMetaValues() { $post = $this->setGlobalPost( 17 ); $this->grantCurrentUserCap( 'edit_post' ); CE_Test_State::$valid_nonces['admin-meta.php'] = 'valid-nonce'; $this->setPostMeta( 17, 'transcript', 'existing transcript' ); $_POST = array( 'comic_nonce' => 'valid-nonce', 'transcript' => array( 'unexpected value' ), ); ceo_handle_edit_save_comic( 17, $post ); $this->assertSame( 'existing transcript', CE_Test_State::$post_meta['17:transcript'] ); unset( $_POST ); } }