Make WordPress Core

Ticket #64567: 64567-tests.2.diff

File 64567-tests.2.diff, 5.1 KB (added by motylanogha, 5 weeks ago)

Refreshed: adds a 5th test covering the 'modifiable text' leak (comment:12). No-flush path for get_attribute_names_with_prefix() — set / remove / change attribute, add_class, agreement with get_attribute(), and modifiable-text regression. Pass against PR #10828 + the one-line guard; fail on trunk.

  • tests/phpunit/tests/html-api/wpHtmlTagProcessor.php

    diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
    index 22ace3890f..da2fcd1e5c 100644
    a b class Tests_HtmlApi_WpHtmlTagProcessor extends WP_UnitTestCase {  
    460460                );
    461461        }
    462462
     463        /**
     464         * Ensures that an attribute added via set_attribute() is reported by
     465         * get_attribute_names_with_prefix() without first flushing the updates
     466         * through get_updated_html().
     467         *
     468         * @ticket 64567
     469         *
     470         * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
     471         */
     472        public function test_get_attribute_names_with_prefix_reflects_set_attribute_without_flushing() {
     473                $processor = new WP_HTML_Tag_Processor( '<div data-foo="bar">Test</div>' );
     474                $processor->next_tag();
     475                $processor->set_attribute( 'data-test-id', '14' );
     476
     477                $this->assertSame(
     478                        array( 'data-foo', 'data-test-id' ),
     479                        $processor->get_attribute_names_with_prefix( 'data-' ),
     480                        'Enqueued attribute added via set_attribute() was not reflected before flushing updates.'
     481                );
     482        }
     483
     484        /**
     485         * Ensures that an attribute removed via remove_attribute() is no longer
     486         * reported by get_attribute_names_with_prefix() without first flushing the
     487         * updates through get_updated_html().
     488         *
     489         * @ticket 64567
     490         *
     491         * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
     492         */
     493        public function test_get_attribute_names_with_prefix_reflects_remove_attribute_without_flushing() {
     494                $processor = new WP_HTML_Tag_Processor( '<div data-foo="bar" data-keep="1">Test</div>' );
     495                $processor->next_tag();
     496                $processor->remove_attribute( 'data-foo' );
     497
     498                $this->assertSame(
     499                        array( 'data-keep' ),
     500                        $processor->get_attribute_names_with_prefix( 'data-' ),
     501                        'Enqueued attribute removal via remove_attribute() was not reflected before flushing updates.'
     502                );
     503        }
     504
     505        /**
     506         * Ensures that a class enqueued via add_class() surfaces the `class`
     507         * attribute in get_attribute_names_with_prefix() without first flushing the
     508         * updates through get_updated_html().
     509         *
     510         * @ticket 64567
     511         *
     512         * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
     513         */
     514        public function test_get_attribute_names_with_prefix_reflects_added_class_without_flushing() {
     515                $processor = new WP_HTML_Tag_Processor( '<div data-foo="bar">Test</div>' );
     516                $processor->next_tag();
     517                $processor->add_class( 'highlight' );
     518
     519                $this->assertSame(
     520                        array( 'class' ),
     521                        $processor->get_attribute_names_with_prefix( 'class' ),
     522                        'Enqueued class attribute created via add_class() was not reflected before flushing updates.'
     523                );
     524        }
     525
     526        /**
     527         * Ensures get_attribute_names_with_prefix() agrees with get_attribute()
     528         * after pending updates, returning each name once with no stale entries.
     529         *
     530         * @ticket 64567
     531         *
     532         * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
     533         */
     534        public function test_get_attribute_names_with_prefix_agrees_with_get_attribute_after_updates() {
     535                $processor = new WP_HTML_Tag_Processor( '<div data-a="1" data-b="2" data-c="3">Test</div>' );
     536                $processor->next_tag();
     537                $processor->set_attribute( 'data-b', 'updated' ); // Change an existing attribute.
     538                $processor->remove_attribute( 'data-c' );         // Remove an existing attribute.
     539                $processor->set_attribute( 'data-d', 'new' );     // Add a new attribute.
     540
     541                $names = $processor->get_attribute_names_with_prefix( 'data-' );
     542                sort( $names );
     543
     544                $this->assertSame(
     545                        array( 'data-a', 'data-b', 'data-d' ),
     546                        $names,
     547                        'Reported attribute names did not reflect the enqueued changes before flushing updates.'
     548                );
     549
     550                foreach ( $names as $name ) {
     551                        $this->assertNotNull(
     552                                $processor->get_attribute( $name ),
     553                                "get_attribute_names_with_prefix() reported '{$name}' but get_attribute() reports it as absent."
     554                        );
     555                }
     556
     557                $this->assertNull(
     558                        $processor->get_attribute( 'data-c' ),
     559                        'Removed attribute data-c should be null via get_attribute().'
     560                );
     561                $this->assertNotContains(
     562                        'data-c',
     563                        $names,
     564                        'Removed attribute data-c should not appear in get_attribute_names_with_prefix().'
     565                );
     566        }
     567
     568        /**
     569         * Ensures the internal 'modifiable text' lexical update enqueued by
     570         * set_modifiable_text() does not leak into get_attribute_names_with_prefix()
     571         * as if it were an attribute name.
     572         *
     573         * The update is stored in the same lexical_updates array as attribute
     574         * changes but under the string key 'modifiable text', so a naive skip that
     575         * only ignores integer keys would report it for any matching prefix.
     576         *
     577         * @ticket 64567
     578         *
     579         * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
     580         */
     581        public function test_get_attribute_names_with_prefix_ignores_modifiable_text_update() {
     582                $processor = new WP_HTML_Tag_Processor( '<script id="x">old</script>' );
     583                $processor->next_tag();
     584                $processor->set_modifiable_text( 'new content' );
     585
     586                $this->assertSame(
     587                        array( 'id' ),
     588                        $processor->get_attribute_names_with_prefix( '' ),
     589                        "The internal 'modifiable text' update key leaked as an attribute name."
     590                );
     591        }
     592
    463593        /**
    464594         * @ticket 56299
    465595         *