diff --git a/tests/phpunit/tests/feed/atom.php b/tests/phpunit/tests/feed/atom.php new file mode 100644 index 0000000000..9e9bed11a5 --- /dev/null +++ b/tests/phpunit/tests/feed/atom.php @@ -0,0 +1,214 @@ +user->create( array( + 'role' => 'author', + 'user_login' => 'test_author', + 'display_name' => 'Test A. Uthor', + ) ); + + // Create a taxonomy + self::$category = self::factory()->category->create_and_get( array( + 'name' => 'Test Category', + 'slug' => 'test-cat', + ) ); + + // Create a few posts + self::$posts = $factory->post->create_many( 42, array( + 'post_author' => self::$user_id, + 'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec velit massa, ultrices eu est suscipit, mattis posuere est. Donec vitae purus lacus. Cras vitae odio odio.', + 'post_excerpt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + ) ); + + // Assign a category to those posts + foreach ( self::$posts as $post ) { + wp_set_object_terms( $post, self::$category->slug, 'category' ); + } + + } + + /** + * Destroy the user we created and related posts. + */ + public static function wpTearDownAfterClass() { + // Delete our user + self::delete_user( self::$user_id ); + + // Delete all of our posts + foreach ( self::$posts as $post ) { + wp_delete_post( $post, true ); + } + + // Delete our taxonomy + wp_delete_category( self::$category->term_id ); + } + + /** + * Setup. + */ + public function setUp() { + parent::setUp(); + + $this->post_count = (int) get_option( 'posts_per_rss' ); + $this->excerpt_only = get_option( 'rss_use_excerpt' ); + } + + /** + * This is a bit of a hack used to buffer feed content. + */ + function do_atom() { + ob_start(); + // Nasty hack! In the future it would better to leverage do_feed( 'atom' ). + global $post; + try { + @require( ABSPATH . 'wp-includes/feed-atom.php' ); + $out = ob_get_clean(); + } catch ( Exception $e ) { + $out = ob_get_clean(); + throw( $e ); + } + return $out; + } + + /** + * Test the element to make sure its present and populated + * with the expected child elements and attributes. + */ + function test_feed_element() { + $this->go_to( '/?feed=atom' ); + $feed = $this->do_atom(); + $xml = xml_to_array( $feed ); + + // Get the child element of . + $atom = xml_find( $xml, 'feed' ); + + // There should only be one child element. + $this->assertCount( 1, $atom ); + + // Verify attributes. + $this->assertEquals( 'http://www.w3.org/2005/Atom', $atom[0]['attributes']['xmlns'] ); + $this->assertEquals( 'http://purl.org/syndication/thread/1.0', $atom[0]['attributes']['xmlns:thr'] ); + $this->assertEquals( site_url( '/wp-atom.php' ) , $atom[0]['attributes']['xml:base'] ); + + // Verify the element is present and contains a child element. + $title = xml_find( $xml, 'feed', 'title' ); + $this->assertEquals( get_option( 'blogname' ), $title[0]['content'] ); + + // Verify the <feed> element is present and contains a <updated> child element. + $updated = xml_find( $xml, 'feed', 'updated' ); + $this->assertEquals( strtotime( get_lastpostmodified() ), strtotime( $updated[0]['content'] ) ); + + // Verify the <feed> element is present and contains a <subtitle> child element. + $subtitle = xml_find( $xml, 'feed', 'subtitle' ); + $this->assertEquals( get_option( 'blogdescription' ), $subtitle[0]['content'] ); + + // Verify the <feed> element is present and contains two <link> child elements. + $link = xml_find( $xml, 'feed', 'link' ); + $this->assertCount( 2, $link ); + + // Verify the <feed> element is present and contains a <link rel="alternate"> child element. + $this->assertEquals( 'alternate', $link[0]['attributes']['rel'] ); + $this->assertEquals( home_url(), $link[0]['attributes']['href'] ); + + // Verify the <feed> element is present and contains a <link rel="href"> child element. + $this->assertEquals( 'self', $link[1]['attributes']['rel'] ); + $this->assertEquals( home_url( '/?feed=atom' ), $link[1]['attributes']['href'] ); + } + + /** + * Validate <entry> child elements. + */ + function test_entry_elements() { + $this->go_to( '/?feed=atom' ); + $feed = $this->do_atom(); + $xml = xml_to_array( $feed ); + + // Get all the <entry> child elements of the <feed> element. + $entries = xml_find( $xml, 'feed', 'entry' ); + + // Verify we are displaying the correct number of posts. + $this->assertCount( $this->post_count, $entries ); + + // We Really only need to test X number of entries unless the content is different + $entries = array_slice( $entries, 1 ); + + // Check each of the desired entries against the known post data. + foreach ( $entries as $key => $entry ) { + + // Get post for comparison + $id = xml_find( $entries[$key]['child'], 'id' ); + preg_match( '/\?p=(\d+)/', $id[0]['content'], $matches ); + $post = get_post( $matches[1] ); + + // Author + $author = xml_find( $entries[$key]['child'], 'author', 'name' ); + $user = new WP_User( $post->post_author ); + $this->assertEquals( $user->display_name, $author[0]['content'] ); + + // Title + $title = xml_find( $entries[$key]['child'], 'title' ); + $this->assertEquals( $post->post_title, $title[0]['content'] ); + + // Link rel="alternate" + $link_alts = xml_find( $entries[$key]['child'], 'link' ); + foreach ( $link_alts as $link_alt ) { + if ( 'alternate' == $link_alt['attributes']['rel'] ) { + $this->assertEquals( get_permalink( $post ), $link_alt['attributes']['href'] ); + } + } + + // Id + $guid = xml_find( $entries[$key]['child'], 'id' ); + $this->assertEquals( $post->guid, $id[0]['content'] ); + + // Updated + $updated = xml_find( $entries[$key]['child'], 'updated' ); + $this->assertEquals( strtotime( $post->post_modified_gmt ), strtotime( $updated[0]['content'] ) ); + + // Published + $published = xml_find( $entries[$key]['child'], 'published' ); + $this->assertEquals( strtotime( $post->post_date_gmt ), strtotime( $published[0]['content'] ) ); + + // Category + foreach ( get_the_category( $post->ID ) as $term ) { + $terms[] = $term->name; + } + $categories = xml_find( $entries[$key]['child'], 'category' ); + foreach ( $categories as $category ) { + $this->assertTrue( in_array( $category['attributes']['term'], $terms ) ); + } + unset( $terms ); + + // Content + if ( ! $this->excerpt_only ) { + $content = xml_find( $entries[$key]['child'], 'content' ); + $this->assertEquals( trim( apply_filters( 'the_content', $post->post_content ) ), trim( $content[0]['content'] ) ); + } + + // Link rel="replies" + $link_replies = xml_find( $entries[$key]['child'], 'link' ); + foreach ( $link_replies as $link_reply ) { + if ( 'replies' == $link_reply['attributes']['rel'] && 'application/atom+xml' == $link_reply['attributes']['type'] ) { + $this->assertEquals( get_post_comments_feed_link( $post->ID, 'atom' ), $link_reply['attributes']['href'] ); + } + } + } + } +} diff --git a/tests/phpunit/tests/feed/rss2.php b/tests/phpunit/tests/feed/rss2.php index 4f4dfed8f6..edd42a543b 100644 --- a/tests/phpunit/tests/feed/rss2.php +++ b/tests/phpunit/tests/feed/rss2.php @@ -1,44 +1,82 @@ <?php /** - * test the RSS 2.0 feed by generating a feed, parsing it, and checking that the + * Test the RSS 2.0 feed by generating a feed, parsing it, and checking that the * parsed contents match the contents of the posts stored in the database. Since * we're using a real XML parser, this confirms that the feed is valid, well formed, * and contains the right stuff. * * @group feed */ -class Tests_Feed_RSS2 extends WP_UnitTestCase { +class Tests_Feeds_RSS2 extends WP_UnitTestCase { static $user_id; static $posts; + static $category; + /** + * Setup a new user and attribute some posts. + */ public static function wpSetUpBeforeClass( $factory ) { - self::$user_id = $factory->user->create(); - self::$posts = $factory->post->create_many( 5, array( - 'post_author' => self::$user_id, + // Create a user + self::$user_id = $factory->user->create( array( + 'role' => 'author', + 'user_login' => 'test_author', + 'display_name' => 'Test A. Uthor', ) ); - } - public static function wpTearDownAfterClass() { - self::delete_user( self::$user_id ); + // Create a taxonomy + self::$category = self::factory()->category->create_and_get( array( + 'name' => 'Test Category', + 'slug' => 'test-cat', + ) ); + // Create a few posts + self::$posts = $factory->post->create_many( 42, array( + 'post_author' => self::$user_id, + 'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec velit massa, ultrices eu est suscipit, mattis posuere est. Donec vitae purus lacus. Cras vitae odio odio.', + 'post_excerpt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + ) ); + + // Assign a category to those posts foreach ( self::$posts as $post ) { - wp_delete_post( $post, true ); + wp_set_object_terms( $post, self::$category->slug, 'category' ); } } + /** + * Destroy the user we created and related posts. + */ + public static function wpTearDownAfterClass() { + // Delete our user + self::delete_user( self::$user_id ); + + // Delete all of our posts + foreach ( self::$posts as $post ) { + wp_delete_post( $post, true ); + } + + // Delete our taxonomy + wp_delete_category( self::$category->term_id ); + } + + /** + * Setup. + */ public function setUp() { parent::setUp(); - $this->post_count = get_option('posts_per_rss'); - $this->excerpt_only = get_option('rss_use_excerpt'); + $this->post_count = (int) get_option( 'posts_per_rss' ); + $this->excerpt_only = get_option( 'rss_use_excerpt' ); // this seems to break something - update_option('use_smilies', false); + update_option( 'use_smilies', false ); } + /** + * This is a bit of a hack used to buffer feed content. + */ function do_rss2() { ob_start(); - // nasty hack + // Nasty hack! In the future it would better to leverage do_feed( 'rss2' ). global $post; try { @require(ABSPATH . 'wp-includes/feed-rss2.php'); @@ -50,61 +88,77 @@ class Tests_Feed_RSS2 extends WP_UnitTestCase { return $out; } - function test_rss() { + /** + * Test the <rss> element to make sure its present and populated + * with the expected child elements and attributes. + */ + function test_rss_element() { $this->go_to( '/?feed=rss2' ); $feed = $this->do_rss2(); - $xml = xml_to_array($feed); + $xml = xml_to_array( $feed ); - // get the rss element - $rss = xml_find($xml, 'rss'); + // Get the <rss> child element of <xml>. + $rss = xml_find( $xml, 'rss' ); - // there should only be one rss element - $this->assertEquals(1, count($rss)); + // There should only be one <rss> child element. + $this->assertEquals( 1, count( $rss ) ); - $this->assertEquals('2.0', $rss[0]['attributes']['version']); - $this->assertEquals('http://purl.org/rss/1.0/modules/content/', $rss[0]['attributes']['xmlns:content']); - $this->assertEquals('http://wellformedweb.org/CommentAPI/', $rss[0]['attributes']['xmlns:wfw']); - $this->assertEquals('http://purl.org/dc/elements/1.1/', $rss[0]['attributes']['xmlns:dc']); + $this->assertEquals( '2.0', $rss[0]['attributes']['version'] ); + $this->assertEquals( 'http://purl.org/rss/1.0/modules/content/', $rss[0]['attributes']['xmlns:content'] ); + $this->assertEquals( 'http://wellformedweb.org/CommentAPI/', $rss[0]['attributes']['xmlns:wfw'] ); + $this->assertEquals( 'http://purl.org/dc/elements/1.1/', $rss[0]['attributes']['xmlns:dc'] ); // rss should have exactly one child element (channel) - $this->assertEquals(1, count($rss[0]['child'])); + $this->assertEquals( 1, count( $rss[0]['child'] ) ); } - function test_channel() { + /** + * [test_channel_element description] + * @return [type] [description] + */ + function test_channel_element() { $this->go_to( '/?feed=rss2' ); $feed = $this->do_rss2(); - $xml = xml_to_array($feed); + $xml = xml_to_array( $feed ); // get the rss -> channel element - $channel = xml_find($xml, 'rss', 'channel'); + $channel = xml_find( $xml, 'rss', 'channel' ); - $this->assertTrue(empty($channel[0]['attributes'])); + // The channel should be free of attributes + $this->assertTrue( empty( $channel[0]['attributes'] ) ); - $title = xml_find($xml, 'rss', 'channel', 'title'); - $this->assertEquals(get_option('blogname'), $title[0]['content']); + // Verify the channel is present and contains a title child element + $title = xml_find( $xml, 'rss', 'channel', 'title' ); + $this->assertEquals( get_option( 'blogname' ), $title[0]['content'] ); - $desc = xml_find($xml, 'rss', 'channel', 'description'); - $this->assertEquals(get_option('blogdescription'), $desc[0]['content']); + $desc = xml_find( $xml, 'rss', 'channel', 'description' ); + $this->assertEquals( get_option( 'blogdescription' ), $desc[0]['content'] ); - $link = xml_find($xml, 'rss', 'channel', 'link'); - $this->assertEquals(get_option('siteurl'), $link[0]['content']); + $link = xml_find( $xml, 'rss', 'channel', 'link' ); + $this->assertEquals( get_option( 'siteurl' ), $link[0]['content'] ); - $pubdate = xml_find($xml, 'rss', 'channel', 'lastBuildDate'); - $this->assertEquals(strtotime(get_lastpostmodified()), strtotime($pubdate[0]['content'])); + $pubdate = xml_find( $xml, 'rss', 'channel', 'lastBuildDate' ); + $this->assertEquals( strtotime( get_lastpostmodified() ), strtotime( $pubdate[0]['content'] ) ); } /** * @ticket UT32 */ - function test_items() { + function test_item_elements() { $this->go_to( '/?feed=rss2' ); $feed = $this->do_rss2(); - $xml = xml_to_array($feed); + $xml = xml_to_array( $feed ); - // get all the rss -> channel -> item elements + // Get all the <item> child elements of the <channel> element $items = xml_find( $xml, 'rss', 'channel', 'item' ); - // check each of the items against the known post data + // Verify we are displaying the correct number of posts. + $this->assertCount( $this->post_count, $items ); + + // We Really only need to test X number of items unless the content is different + $items = array_slice( $items, 1 ); + + // Check each of the desired entries against the known post data foreach ( $items as $key => $item ) { // Get post for comparison @@ -112,28 +166,28 @@ class Tests_Feed_RSS2 extends WP_UnitTestCase { preg_match( '/\?p=(\d+)/', $guid[0]['content'], $matches ); $post = get_post( $matches[1] ); - // title + // Title $title = xml_find( $items[$key]['child'], 'title' ); $this->assertEquals( $post->post_title, $title[0]['content'] ); - // link + // Link $link = xml_find( $items[$key]['child'], 'link' ); $this->assertEquals( get_permalink( $post ), $link[0]['content'] ); - // comment link + // Comment link $comments_link = xml_find( $items[$key]['child'], 'comments' ); - $this->assertEquals( get_permalink( $post) . '#respond', $comments_link[0]['content'] ); + $this->assertEquals( get_permalink( $post ) . '#respond', $comments_link[0]['content'] ); - // pub date + // Pub date $pubdate = xml_find( $items[$key]['child'], 'pubDate' ); $this->assertEquals( strtotime( $post->post_date_gmt ), strtotime( $pubdate[0]['content'] ) ); - // author + // Author $creator = xml_find( $items[$key]['child'], 'dc:creator' ); $user = new WP_User( $post->post_author ); - $this->assertEquals( $user->user_login, $creator[0]['content'] ); + $this->assertEquals( $user->display_name, $creator[0]['content'] ); - // categories (perhaps multiple) + // Categories (perhaps multiple) $categories = xml_find( $items[$key]['child'], 'category' ); $cats = array(); foreach ( get_the_category( $post->ID ) as $term ) { @@ -147,34 +201,34 @@ class Tests_Feed_RSS2 extends WP_UnitTestCase { } } $cats = array_filter( $cats ); - // should be the same number of categories + // Should be the same number of categories $this->assertEquals( count( $cats ), count( $categories ) ); // ..with the same names foreach ( $cats as $id => $cat ) { - $this->assertEquals( $cat, $categories[$id]['content']); + $this->assertEquals( $cat, $categories[$id]['content'] ); } // GUID $guid = xml_find( $items[$key]['child'], 'guid' ); - $this->assertEquals('false', $guid[0]['attributes']['isPermaLink'] ); + $this->assertEquals( 'false', $guid[0]['attributes']['isPermaLink'] ); $this->assertEquals( $post->guid, $guid[0]['content'] ); - // description/excerpt - if ( !empty( $post->post_excerpt ) ) { + // Description / Excerpt + if ( ! empty( $post->post_excerpt ) ) { $description = xml_find( $items[$key]['child'], 'description' ); $this->assertEquals( trim( $post->post_excerpt ), trim( $description[0]['content'] ) ); } - // post content - if ( !$this->excerpt_only ) { + // Post content + if ( ! $this->excerpt_only ) { $content = xml_find( $items[$key]['child'], 'content:encoded' ); $this->assertEquals( trim( apply_filters( 'the_content', $post->post_content ) ), trim( $content[0]['content'] ) ); } - // comment rss + // Comment rss $comment_rss = xml_find( $items[$key]['child'], 'wfw:commentRss' ); - $this->assertEquals( html_entity_decode( get_post_comments_feed_link( $post->ID) ), $comment_rss[0]['content'] ); + $this->assertEquals( html_entity_decode( get_post_comments_feed_link( $post->ID ) ), $comment_rss[0]['content'] ); } } @@ -186,7 +240,7 @@ class Tests_Feed_RSS2 extends WP_UnitTestCase { $this->go_to( '/?feed=rss2' ); $feed = $this->do_rss2(); - $xml = xml_to_array($feed); + $xml = xml_to_array( $feed ); // get all the rss -> channel -> item elements $items = xml_find( $xml, 'rss', 'channel', 'item' ); @@ -209,4 +263,5 @@ class Tests_Feed_RSS2 extends WP_UnitTestCase { remove_filter( 'comments_open', '__return_false' ); } + }