Ticket #35160: 35160.patch
File 35160.patch, 18.0 KB (added by , 7 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 */ 11 class 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 */ 8 class 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 */ 11 class 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 }