WordPress.org

Make WordPress Core

Ticket #35160: 35160.patch

File 35160.patch, 18.0 KB (added by stevenkword, 6 years ago)
  • tests/phpunit/tests/feeds/atom.php

     
     1<?php
     2
     3/**
     4 * Test the Atom feed by generating a feed, parsing it, and checking that the
     5 * parsed contents match the contents of the posts stored in the database.  Since
     6 * we're using a real XML parser, this confirms that the feed is valid, well formed,
     7 * and contains the right stuff.
     8 *
     9 * @group feeds
     10 */
     11class Tests_Feeds_Atom extends WP_UnitTestCase {
     12        static $user_id;
     13        static $posts;
     14
     15        /**
     16         * Setup a new user and attribute some posts.
     17         */
     18        public static function wpSetUpBeforeClass( $factory ) {
     19                self::$user_id = $factory->user->create();
     20                self::$posts = $factory->post->create_many( 5, array(
     21                        'post_author' => self::$user_id,
     22                ) );
     23        }
     24
     25        /**
     26         * Destroy the user we created and related posts.
     27         */
     28        public static function wpTearDownAfterClass() {
     29                self::delete_user( self::$user_id );
     30
     31                foreach ( self::$posts as $post ) {
     32                        wp_delete_post( $post, true );
     33                }
     34        }
     35
     36        /**
     37         * Setup.
     38         */
     39        public function setUp() {
     40                parent::setUp();
     41        }
     42
     43        /**
     44         * This is a bit of a hack used to buffer feed content.
     45         */
     46        function do_atom() {
     47                ob_start();
     48                // Nasty hack! In the future it would better to leverage do_feed( 'atom' ).
     49                global $post;
     50                try {
     51                        @require( ABSPATH . 'wp-includes/feed-atom.php' );
     52                        $out = ob_get_clean();
     53                } catch ( Exception $e ) {
     54                        $out = ob_get_clean();
     55                        throw( $e );
     56                }
     57                return $out;
     58        }
     59
     60        /**
     61         * Test the <feed> element to make sure its present and populated
     62         * with the expected child elements and attributes.
     63         */
     64        function test_feed_element() {
     65                $this->go_to( '/?feed=atom' );
     66                $feed = $this->do_atom();
     67                $xml = xml_to_array( $feed );
     68
     69                // Get the <feed> child element of <xml>.
     70                $atom = xml_find( $xml, 'feed' );
     71
     72                // There should only be one <feed> child element.
     73                $this->assertEquals( 1, count( $atom ) );
     74
     75                // Verify attributes.
     76                $this->assertEquals( 'http://www.w3.org/2005/Atom', $atom[0]['attributes']['xmlns'] );
     77                $this->assertEquals( 'http://purl.org/syndication/thread/1.0', $atom[0]['attributes']['xmlns:thr'] );
     78                $this->assertEquals( site_url( '/wp-atom.php' ) , $atom[0]['attributes']['xml:base'] );
     79
     80                // Verify the <feed> element is present and contains a <title> child element.
     81                $title = xml_find( $xml, 'feed', 'title' );
     82                $this->assertEquals( get_option( 'blogname' ), $title[0]['content'] );
     83
     84                // Verify the <feed> element is present and contains a <updated> child element.
     85                $updated = xml_find( $xml, 'feed', 'updated' );
     86                $this->assertEquals( strtotime( get_lastpostmodified() ), strtotime( $updated[0]['content'] ) );
     87
     88                // Verify the <feed> element is present and contains a <subtitle> child element.
     89                $subtitle = xml_find( $xml, 'feed', 'subtitle' );
     90                $this->assertEquals( get_option( 'blogdescription' ), $subtitle[0]['content'] );
     91
     92                // Verify the <feed> element is present and contains two <link> child elements.
     93                $link = xml_find( $xml, 'feed', 'link' );
     94                $this->assertEquals( 2, count( $link ) );
     95
     96                // Verify the <feed> element is present and contains a <link rel="alternate"> child element.
     97                $this->assertEquals( 'alternate', $link[0]['attributes']['rel'] );
     98                $this->assertEquals( home_url(), $link[0]['attributes']['href'] );
     99
     100                // Verify the <feed> element is present and contains a <link rel="href"> child element.
     101                $this->assertEquals( 'self', $link[1]['attributes']['rel'] );
     102                $this->assertEquals( home_url( '/?feed=atom' ), $link[1]['attributes']['href'] );
     103        }
     104
     105        /**
     106         * Validate <entry> child elements.
     107         */
     108        function test_entry_elements() {
     109                $this->go_to( '/?feed=atom' );
     110                $feed = $this->do_atom();
     111                $xml = xml_to_array( $feed );
     112
     113                // Get all the <entry> child elements of the <feed> element.
     114                $entries = xml_find( $xml, 'feed', 'entry' );
     115
     116                // Check each of the entries against the known post data.
     117                foreach ( $entries as $key => $entry ) {
     118
     119                        // Get post for comparison
     120                        $id = xml_find( $entries[$key]['child'], 'id' );
     121                        preg_match( '/\?p=(\d+)/', $id[0]['content'], $matches );
     122                        $post = get_post( $matches[1] );
     123
     124                        // Author
     125                        $author = xml_find( $entries[$key]['child'], 'author', 'name' );
     126                        $user = new WP_User( $post->post_author );
     127                        $this->assertEquals( $user->user_login, $author[0]['content'] );
     128
     129                        // Title
     130                        $title = xml_find( $entries[$key]['child'], 'title' );
     131                        $this->assertEquals( $post->post_title, $title[0]['content'] );
     132
     133                        // Link rel="alternate"
     134                        $link_alts = xml_find( $entries[$key]['child'], 'link' );
     135                        foreach( $link_alts as $link_alt ) {
     136                                if( 'alternate' == $link_alt['attributes']['rel'] ) {
     137                                        $this->assertEquals( get_permalink( $post ), $link_alt['attributes']['href'] );
     138                                }
     139                        }
     140
     141                        // Id
     142                        $guid = xml_find( $entries[$key]['child'], 'id' );
     143                        $this->assertEquals( $post->guid, $id[0]['content'] );
     144
     145                        // Updated
     146                        $updated = xml_find( $entries[$key]['child'], 'updated');
     147                        $this->assertEquals( strtotime( $post->post_modified_gmt ), strtotime( $updated[0]['content'] ) );
     148
     149                        // Published
     150                        $published = xml_find( $entries[$key]['child'], 'published');
     151                        $this->assertEquals( strtotime( $post->post_date_gmt ), strtotime( $published[0]['content'] ) );
     152
     153                        // Category
     154                        foreach ( get_the_category( $post->ID ) as $term ) {
     155                                $terms[] = $term->name;
     156                        }
     157                        $categories = xml_find( $entries[$key]['child'], 'category' );
     158                        foreach( $categories as $category ) {
     159                                $this->assertTrue( in_array( $category['attributes']['term'], $terms ) );
     160                        }
     161                        unset( $terms );
     162
     163                        // Content
     164                        if ( !$this->excerpt_only ) {
     165                                $content = xml_find( $entries[$key]['child'], 'content' );
     166                                $this->assertEquals( trim( apply_filters( 'the_content', $post->post_content ) ), trim( $content[0]['content'] ) );
     167                        }
     168
     169                        // Link rel="replies"
     170                        $link_replies = xml_find( $entries[$key]['child'], 'link' );
     171                        foreach( $link_replies as $link_reply ) {
     172                                if( 'replies' == $link_reply['attributes']['rel'] && 'application/atom+xml' == $link_reply['attributes']['type'] ) {
     173                                        $this->assertEquals( get_post_comments_feed_link( $post->ID, 'atom' ), $link_reply['attributes']['href'] );
     174                                }
     175                        }
     176                }
     177        }
     178}
  • tests/phpunit/tests/feeds/common.php

    Property changes on: tests/phpunit/tests/feeds/atom.php
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1<?php
     2
     3/**
     4 *      Tests common to all feeds
     5 *
     6 * @group feeds
     7 */
     8class Tests_Feeds_Common extends WP_UnitTestCase {
     9        static $user_id;
     10        static $posts;
     11
     12        /**
     13         * [wpSetUpBeforeClass description]
     14         * @param  [type] $factory [description]
     15         * @return [type]          [description]
     16         */
     17        public static function wpSetUpBeforeClass( $factory ) {
     18                self::$user_id = $factory->user->create();
     19                self::$posts = $factory->post->create_many( 5, array(
     20                        'post_author' => self::$user_id,
     21                ) );
     22        }
     23
     24        /**
     25         * [wpTearDownAfterClass description]
     26         * @return [type] [description]
     27         */
     28        public static function wpTearDownAfterClass() {
     29                self::delete_user( self::$user_id );
     30
     31                foreach ( self::$posts as $post ) {
     32                        wp_delete_post( $post, true );
     33                }
     34        }
     35
     36        /**
     37         * [setUp description]
     38         */
     39        public function setUp() {
     40                parent::setUp();
     41
     42                $this->post_count = get_option('posts_per_rss');
     43                $this->excerpt_only = get_option('rss_use_excerpt');
     44                // this seems to break something
     45                update_option('use_smilies', false);
     46        }
     47
     48        /*
     49         * Check to make sure we are not rendering feed templates for invalid feed endpoints.
     50         * e.g.) https://example.com/wp-content/feed/
     51         *
     52         * @ticket 30210
     53         */
     54        function test_invalid_feed_endpoints() {
     55                global $wp_rewrite;
     56
     57                $wp_rewrite->init();
     58                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
     59
     60                // An example of an invalid feed endpoint
     61                $this->go_to( content_url( 'feed/' ) );
     62
     63                // This must be globalized after calling `WP_UnitTestCase::go_to` which references $GLOBALS['wp_query'] and not $wp_query.
     64                global $wp_query;
     65
     66                // Queries performed on invalid feed endpoints should never contain posts.
     67                $this->assertFalse( $wp_query->have_posts() );
     68
     69                // This is the assertion.  Once the exception is thrown in do_feed, execution stops, preventing futher assertions.
     70                $this->setExpectedException( 'WPDieException', 'ERROR: This is not a valid feed.' );
     71                do_feed();
     72        }
     73
     74        /*
     75         * Make sure the requested feed is registered before rendering the requested template.
     76         *
     77         * @ticket 30210
     78         */
     79        function test_nonexistent_feeds() {
     80                global $wp_rewrite;
     81                $feedname = 'badfeed';
     82
     83                // Unregister the feed if it exists
     84                if ( in_array( $feedname, $wp_rewrite->feeds ) ) {
     85                        unset( $wp_rewrite->feeds->feedname );
     86                        $hook = 'do_feed_' . $feedname;
     87                        // Remove default function hook
     88                        remove_action( $hook, $hook );
     89                }
     90
     91                $this->go_to( '/?feed=' . $feedname );
     92
     93                // This must be globalized after calling `WP_UnitTestCase::go_to` which references $GLOBALS['wp_query'] and not $wp_query.
     94                global $wp_query;
     95
     96                // This is the assertion.  Once the exception is thrown in do_feed, execution stops, preventing futher assertions.
     97                $this->setExpectedException( 'WPDieException', 'ERROR: This is not a valid feed template.' );
     98                do_feed();
     99        }
     100
     101        /**
     102         * [test_no_posts_rss description]
     103         * @return [type] [description]
     104         */
     105        function test_no_posts_rss() {
     106                global $wp_query;
     107
     108                // Backups the original $wp_query
     109                $wp_query_orig = wp_clone( $wp_query );
     110
     111                // Sets an empty query
     112                $wp_query = new WP_Query();
     113
     114                $exceptionMessage = '';
     115
     116                try {
     117                        do_feed();
     118                } catch ( WPDieException $e ) {
     119                        $exceptionMessage = $e->getMessage();
     120                }
     121
     122                $this->assertEquals( 'ERROR: This is not a valid feed.', $exceptionMessage, 'Expecting a 404.' );
     123
     124                // Restores the original $wp_query
     125                $wp_query = $wp_query_orig;
     126        }
     127
     128}
  • tests/phpunit/tests/feeds/rss2.php

    Property changes on: tests/phpunit/tests/feeds/common.php
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1<?php
     2
     3/**
     4 * Test the RSS 2.0 feed by generating a feed, parsing it, and checking that the
     5 * parsed contents match the contents of the posts stored in the database.  Since
     6 * we're using a real XML parser, this confirms that the feed is valid, well formed,
     7 * and contains the right stuff.
     8 *
     9 * @group feeds
     10 */
     11class Tests_Feeds_RSS2 extends WP_UnitTestCase {
     12        static $user_id;
     13        static $posts;
     14
     15        /**
     16         * Setup a new user and attribute some posts.
     17         */
     18        public static function wpSetUpBeforeClass( $factory ) {
     19                self::$user_id = $factory->user->create();
     20                self::$posts = $factory->post->create_many( 5, array(
     21                        'post_author' => self::$user_id,
     22                ) );
     23        }
     24
     25        /**
     26         * Destroy the user we created and related posts.
     27         */
     28        public static function wpTearDownAfterClass() {
     29                self::delete_user( self::$user_id );
     30
     31                foreach ( self::$posts as $post ) {
     32                        wp_delete_post( $post, true );
     33                }
     34        }
     35
     36        /**
     37         * Setup.
     38         */
     39        public function setUp() {
     40                parent::setUp();
     41
     42                $this->post_count = get_option('posts_per_rss');
     43                $this->excerpt_only = get_option('rss_use_excerpt');
     44                // this seems to break something
     45                update_option('use_smilies', false);
     46        }
     47
     48        /**
     49         * This is a bit of a hack used to buffer feed content.
     50         */
     51        function do_rss2() {
     52                ob_start();
     53                // Nasty hack! In the future it would better to leverage do_feed( 'rss2' ).
     54                global $post;
     55                try {
     56                        @require(ABSPATH . 'wp-includes/feed-rss2.php');
     57                        $out = ob_get_clean();
     58                } catch (Exception $e) {
     59                        $out = ob_get_clean();
     60                        throw($e);
     61                }
     62                return $out;
     63        }
     64
     65        /**
     66         * Test the <rss> element to make sure its present and populated
     67         * with the expected child elements and attributes.
     68         */
     69        function test_rss_element() {
     70                $this->go_to( '/?feed=rss2' );
     71                $feed = $this->do_rss2();
     72                $xml = xml_to_array($feed);
     73
     74                // Get the <rss> child element of <xml>.
     75                $rss = xml_find( $xml, 'rss' );
     76
     77                // There should only be one <rss> child element.
     78                $this->assertEquals( 1, count( $rss ) );
     79
     80                $this->assertEquals( '2.0', $rss[0]['attributes']['version'] );
     81                $this->assertEquals( 'http://purl.org/rss/1.0/modules/content/', $rss[0]['attributes']['xmlns:content'] );
     82                $this->assertEquals( 'http://wellformedweb.org/CommentAPI/', $rss[0]['attributes']['xmlns:wfw'] );
     83                $this->assertEquals( 'http://purl.org/dc/elements/1.1/', $rss[0]['attributes']['xmlns:dc'] );
     84
     85                // rss should have exactly one child element (channel)
     86                $this->assertEquals( 1, count( $rss[0]['child'] ) );
     87        }
     88
     89        /**
     90         * [test_channel_element description]
     91         * @return [type] [description]
     92         */
     93        function test_channel_element() {
     94                $this->go_to( '/?feed=rss2' );
     95                $feed = $this->do_rss2();
     96                $xml = xml_to_array($feed);
     97
     98                // get the rss -> channel element
     99                $channel = xml_find($xml, 'rss', 'channel');
     100
     101                // The channel should be free of attributes
     102                $this->assertTrue(empty($channel[0]['attributes']));
     103
     104                // Verify the channel is present and contains a title child element
     105                $title = xml_find($xml, 'rss', 'channel', 'title');
     106                $this->assertEquals(get_option('blogname'), $title[0]['content']);
     107
     108                $desc = xml_find($xml, 'rss', 'channel', 'description');
     109                $this->assertEquals(get_option('blogdescription'), $desc[0]['content']);
     110
     111                $link = xml_find($xml, 'rss', 'channel', 'link');
     112                $this->assertEquals(get_option('siteurl'), $link[0]['content']);
     113
     114                $pubdate = xml_find($xml, 'rss', 'channel', 'lastBuildDate');
     115                $this->assertEquals(strtotime(get_lastpostmodified()), strtotime($pubdate[0]['content']));
     116        }
     117
     118        /**
     119         * @ticket UT32
     120         */
     121        function test_item_elements() {
     122                $this->go_to( '/?feed=rss2' );
     123                $feed = $this->do_rss2();
     124                $xml = xml_to_array($feed);
     125
     126                // get all the rss -> channel -> item elements
     127                $items = xml_find( $xml, 'rss', 'channel', 'item' );
     128
     129                // check each of the items against the known post data
     130                foreach ( $items as $key => $item ) {
     131
     132                        // Get post for comparison
     133                        $guid = xml_find( $items[$key]['child'], 'guid' );
     134                        preg_match( '/\?p=(\d+)/', $guid[0]['content'], $matches );
     135                        $post = get_post( $matches[1] );
     136
     137                        // title
     138                        $title = xml_find( $items[$key]['child'], 'title' );
     139                        $this->assertEquals( $post->post_title, $title[0]['content'] );
     140
     141                        // link
     142                        $link = xml_find( $items[$key]['child'], 'link' );
     143                        $this->assertEquals( get_permalink( $post ), $link[0]['content'] );
     144
     145                        // comment link
     146                        $comments_link = xml_find( $items[$key]['child'], 'comments' );
     147                        $this->assertEquals( get_permalink( $post) . '#respond', $comments_link[0]['content'] );
     148
     149                        // pub date
     150                        $pubdate = xml_find( $items[$key]['child'], 'pubDate' );
     151                        $this->assertEquals( strtotime( $post->post_date_gmt ), strtotime( $pubdate[0]['content'] ) );
     152
     153                        // author
     154                        $creator = xml_find( $items[$key]['child'], 'dc:creator' );
     155                        $user = new WP_User( $post->post_author );
     156                        $this->assertEquals( $user->user_login, $creator[0]['content'] );
     157
     158                        // categories (perhaps multiple)
     159                        $categories = xml_find( $items[$key]['child'], 'category' );
     160                        $cats = array();
     161                        foreach ( get_the_category( $post->ID ) as $term ) {
     162                                $cats[] = $term->name;
     163                        }
     164
     165                        $tags = get_the_tags( $post->ID );
     166                        if ( $tags ) {
     167                                foreach ( get_the_tags( $post->ID ) as $term ) {
     168                                        $cats[] = $term->name;
     169                                }
     170                        }
     171                        $cats = array_filter( $cats );
     172                        // should be the same number of categories
     173                        $this->assertEquals( count( $cats ), count( $categories ) );
     174
     175                        // ..with the same names
     176                        foreach ( $cats as $id => $cat ) {
     177                                $this->assertEquals( $cat, $categories[$id]['content']);
     178                        }
     179
     180                        // GUID
     181                        $guid = xml_find( $items[$key]['child'], 'guid' );
     182                        $this->assertEquals('false', $guid[0]['attributes']['isPermaLink'] );
     183                        $this->assertEquals( $post->guid, $guid[0]['content'] );
     184
     185                        // description/excerpt
     186                        if ( !empty( $post->post_excerpt ) ) {
     187                                $description = xml_find( $items[$key]['child'], 'description' );
     188                                $this->assertEquals( trim( $post->post_excerpt ), trim( $description[0]['content'] ) );
     189                        }
     190
     191                        // post content
     192                        if ( !$this->excerpt_only ) {
     193                                $content = xml_find( $items[$key]['child'], 'content:encoded' );
     194                                $this->assertEquals( trim( apply_filters( 'the_content', $post->post_content ) ), trim( $content[0]['content'] ) );
     195                        }
     196
     197                        // comment rss
     198                        $comment_rss = xml_find( $items[$key]['child'], 'wfw:commentRss' );
     199                        $this->assertEquals( html_entity_decode( get_post_comments_feed_link( $post->ID) ), $comment_rss[0]['content'] );
     200                }
     201        }
     202
     203        /**
     204         * @ticket 9134
     205         */
     206        function test_items_comments_closed() {
     207                add_filter( 'comments_open', '__return_false' );
     208
     209                $this->go_to( '/?feed=rss2' );
     210                $feed = $this->do_rss2();
     211                $xml = xml_to_array($feed);
     212
     213                // get all the rss -> channel -> item elements
     214                $items = xml_find( $xml, 'rss', 'channel', 'item' );
     215
     216                // check each of the items against the known post data
     217                foreach ( $items as $key => $item ) {
     218                        // Get post for comparison
     219                        $guid = xml_find( $items[$key]['child'], 'guid' );
     220                        preg_match( '/\?p=(\d+)/', $guid[0]['content'], $matches );
     221                        $post = get_post( $matches[1] );
     222
     223                        // comment link
     224                        $comments_link = xml_find( $items[ $key ]['child'], 'comments' );
     225                        $this->assertEmpty( $comments_link );
     226
     227                        // comment rss
     228                        $comment_rss = xml_find( $items[ $key ]['child'], 'wfw:commentRss' );
     229                        $this->assertEmpty( $comment_rss );
     230                }
     231
     232                remove_filter( 'comments_open', '__return_false' );
     233        }
     234
     235}