<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[51997] trunk/tests/phpunit/tests/admin: Tests: Split `WP_Posts_List_Table` and `WP_Comments_List_Table` tests into two separate files for clarity.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/51997">51997</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/51997","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>SergeyBiryukov</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-11-03 00:48:42 +0000 (Wed, 03 Nov 2021)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Tests: Split `WP_Posts_List_Table` and `WP_Comments_List_Table` tests into two separate files for clarity.
These were previously combined in the `includesListTable.php` file. Since the tests were specific neither to the `_get_list_table()` function nor the parent `WP_List_Table` class, the naming was confusing, which should now be resolved.
Follow-up to <a href="https://core.trac.wordpress.org/changeset/31730">[31730]</a>, <a href="https://core.trac.wordpress.org/changeset/38854">[38854]</a>, <a href="https://core.trac.wordpress.org/changeset/40297">[40297]</a>, <a href="https://core.trac.wordpress.org/changeset/48151">[48151]</a>, <a href="https://core.trac.wordpress.org/changeset/48521">[48521]</a>, <a href="https://core.trac.wordpress.org/changeset/49190">[49190]</a>, <a href="https://core.trac.wordpress.org/changeset/51993">[51993]</a>.
See <a href="https://core.trac.wordpress.org/ticket/53363">#53363</a>.</pre>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsadminwpCommentsListTablephp">trunk/tests/phpunit/tests/admin/wpCommentsListTable.php</a></li>
<li><a href="#trunktestsphpunittestsadminwpPostsListTablephp">trunk/tests/phpunit/tests/admin/wpPostsListTable.php</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsadminincludesListTablephp">trunk/tests/phpunit/tests/admin/includesListTable.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunktestsphpunittestsadminincludesListTablephp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/admin/includesListTable.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/admin/includesListTable.php 2021-11-02 23:18:46 UTC (rev 51996)
+++ trunk/tests/phpunit/tests/admin/includesListTable.php 2021-11-03 00:48:42 UTC (rev 51997)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,514 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-/**
- * @group admin
- */
-class Tests_Admin_IncludesListTable extends WP_UnitTestCase {
- protected static $top = array();
- protected static $children = array();
- protected static $grandchildren = array();
- protected static $post_ids = array();
-
- /**
- * @var WP_Posts_List_Table
- */
- protected $table;
-
- function set_up() {
- parent::set_up();
- $this->table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => 'edit-page' ) );
- }
-
- public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
- // Note that our top/children/grandchildren arrays are 1-indexed.
-
- // Create top-level pages.
- $num_posts = 5;
- foreach ( range( 1, $num_posts ) as $i ) {
- $p = $factory->post->create_and_get(
- array(
- 'post_type' => 'page',
- 'post_title' => sprintf( 'Top Level Page %d', $i ),
- )
- );
-
- self::$top[ $i ] = $p;
- self::$post_ids[] = $p->ID;
- }
-
- // Create child pages.
- $num_children = 3;
- foreach ( self::$top as $top => $top_page ) {
- foreach ( range( 1, $num_children ) as $i ) {
- $p = $factory->post->create_and_get(
- array(
- 'post_type' => 'page',
- 'post_parent' => $top_page->ID,
- 'post_title' => sprintf( 'Child %d', $i ),
- )
- );
-
- self::$children[ $top ][ $i ] = $p;
- self::$post_ids[] = $p->ID;
- }
- }
-
- // Create grand-child pages for the third and fourth top-level pages.
- $num_grandchildren = 3;
- foreach ( range( 3, 4 ) as $top ) {
- foreach ( self::$children[ $top ] as $child => $child_page ) {
- foreach ( range( 1, $num_grandchildren ) as $i ) {
- $p = $factory->post->create_and_get(
- array(
- 'post_type' => 'page',
- 'post_parent' => $child_page->ID,
- 'post_title' => sprintf( 'Grandchild %d', $i ),
- )
- );
-
- self::$grandchildren[ $top ][ $child ][ $i ] = $p;
- self::$post_ids[] = $p->ID;
- }
- }
- }
- }
-
- /**
- * @ticket 15459
- *
- * @covers WP_Posts_List_Table::display_rows
- * @covers WP_Posts_List_Table::set_hierarchical_display
- */
- function test_list_hierarchical_pages_first_page() {
- $this->_test_list_hierarchical_page(
- array(
- 'paged' => 1,
- 'posts_per_page' => 2,
- ),
- array(
- self::$top[1]->ID,
- self::$children[1][1]->ID,
- )
- );
- }
-
- /**
- * @ticket 15459
- *
- * @covers WP_Posts_List_Table::display_rows
- * @covers WP_Posts_List_Table::set_hierarchical_display
- */
- function test_list_hierarchical_pages_second_page() {
- $this->_test_list_hierarchical_page(
- array(
- 'paged' => 2,
- 'posts_per_page' => 2,
- ),
- array(
- self::$top[1]->ID,
- self::$children[1][2]->ID,
- self::$children[1][3]->ID,
- )
- );
- }
-
- /**
- * @ticket 15459
- *
- * @covers WP_Posts_List_Table::display_rows
- * @covers WP_Posts_List_Table::set_hierarchical_display
- */
- function test_search_hierarchical_pages_first_page() {
- $this->_test_list_hierarchical_page(
- array(
- 'paged' => 1,
- 'posts_per_page' => 2,
- 's' => 'Child',
- ),
- array(
- self::$children[1][1]->ID,
- self::$children[1][2]->ID,
- )
- );
- }
-
- /**
- * @ticket 15459
- *
- * @covers WP_Posts_List_Table::display_rows
- * @covers WP_Posts_List_Table::set_hierarchical_display
- */
- function test_search_hierarchical_pages_second_page() {
- $this->_test_list_hierarchical_page(
- array(
- 'paged' => 2,
- 'posts_per_page' => 2,
- 's' => 'Top',
- ),
- array(
- self::$top[3]->ID,
- self::$top[4]->ID,
- )
- );
- }
-
- /**
- * @ticket 15459
- *
- * @covers WP_Posts_List_Table::display_rows
- * @covers WP_Posts_List_Table::set_hierarchical_display
- */
- function test_grandchildren_hierarchical_pages_first_page() {
- // Page 6 is the first page with grandchildren.
- $this->_test_list_hierarchical_page(
- array(
- 'paged' => 6,
- 'posts_per_page' => 2,
- ),
- array(
- self::$top[3]->ID,
- self::$children[3][1]->ID,
- self::$grandchildren[3][1][1]->ID,
- self::$grandchildren[3][1][2]->ID,
- )
- );
- }
-
- /**
- * @ticket 15459
- *
- * @covers WP_Posts_List_Table::display_rows
- * @covers WP_Posts_List_Table::set_hierarchical_display
- */
- function test_grandchildren_hierarchical_pages_second_page() {
- // Page 7 is the second page with grandchildren.
- $this->_test_list_hierarchical_page(
- array(
- 'paged' => 7,
- 'posts_per_page' => 2,
- ),
- array(
- self::$top[3]->ID,
- self::$children[3][1]->ID,
- self::$grandchildren[3][1][3]->ID,
- self::$children[3][2]->ID,
- )
- );
- }
-
- /**
- * Helper function to test the output of a page which uses `WP_Posts_List_Table`.
- *
- * @param array $args Query args for the list of pages.
- * @param array $expected_ids Expected IDs of pages returned.
- */
- protected function _test_list_hierarchical_page( array $args, array $expected_ids ) {
- if ( PHP_VERSION_ID >= 80100 ) {
- /*
- * For the time being, ignoring PHP 8.1 "null to non-nullable" deprecations coming in
- * via hooked in filter functions until a more structural solution to the
- * "missing input validation" conundrum has been architected and implemented.
- */
- $this->expectDeprecation();
- $this->expectDeprecationMessageMatches( '`Passing null to parameter \#[0-9]+ \(\$[^\)]+\) of type [^ ]+ is deprecated`' );
- }
-
- $matches = array();
-
- $_REQUEST['paged'] = $args['paged'];
- $GLOBALS['per_page'] = $args['posts_per_page'];
-
- $args = array_merge(
- array(
- 'post_type' => 'page',
- ),
- $args
- );
-
- // Mimic the behaviour of `wp_edit_posts_query()`:
- if ( ! isset( $args['orderby'] ) ) {
- $args['orderby'] = 'menu_order title';
- $args['order'] = 'asc';
- $args['posts_per_page'] = -1;
- $args['posts_per_archive_page'] = -1;
- }
-
- // Effectively ignore the output until retrieving it later via `getActualOutput()`.
- $this->expectOutputRegex( '`.`' );
-
- $pages = new WP_Query( $args );
-
- $this->table->set_hierarchical_display( true );
- $this->table->display_rows( $pages->posts );
- $output = $this->getActualOutput();
-
- // Clean up.
- unset( $_REQUEST['paged'] );
- unset( $GLOBALS['per_page'] );
-
- preg_match_all( '|<tr[^>]*>|', $output, $matches );
-
- $this->assertCount( count( $expected_ids ), array_keys( $matches[0] ) );
-
- foreach ( $expected_ids as $id ) {
- $this->assertStringContainsString( sprintf( 'id="post-%d"', $id ), $output );
- }
- }
-
- /**
- * @ticket 37407
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- function test_filter_button_should_not_be_shown_if_there_are_no_posts() {
- // Set post type to a non-existent one.
- $this->table->screen->post_type = 'foo';
-
- ob_start();
- $this->table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringNotContainsString( 'id="post-query-submit"', $output );
- }
-
- /**
- * @ticket 37407
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- function test_months_dropdown_should_not_be_shown_if_there_are_no_posts() {
- // Set post type to a non-existent one.
- $this->table->screen->post_type = 'foo';
-
- ob_start();
- $this->table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringNotContainsString( 'id="filter-by-date"', $output );
- }
-
- /**
- * @ticket 37407
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- function test_category_dropdown_should_not_be_shown_if_there_are_no_posts() {
- // Set post type to a non-existent one.
- $this->table->screen->post_type = 'foo';
-
- ob_start();
- $this->table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringNotContainsString( 'id="cat"', $output );
- }
-
- /**
- * @ticket 38341
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- public function test_empty_trash_button_should_not_be_shown_if_there_are_no_posts() {
- // Set post type to a non-existent one.
- $this->table->screen->post_type = 'foo';
-
- ob_start();
- $this->table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringNotContainsString( 'id="delete_all"', $output );
- }
-
- /**
- * @ticket 40188
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- public function test_filter_button_should_not_be_shown_if_there_are_no_comments() {
- $table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
-
- ob_start();
- $table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringNotContainsString( 'id="post-query-submit"', $output );
- }
-
- /**
- * @ticket 40188
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- public function test_filter_button_should_be_shown_if_there_are_comments() {
- $post_id = self::factory()->post->create();
- $comment_id = self::factory()->comment->create(
- array(
- 'comment_post_ID' => $post_id,
- 'comment_approved' => '1',
- )
- );
-
- $table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
- $table->prepare_items();
-
- ob_start();
- $table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringContainsString( 'id="post-query-submit"', $output );
- }
-
- /**
- * @ticket 40188
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- public function test_filter_comment_type_dropdown_should_be_shown_if_there_are_comments() {
- $post_id = self::factory()->post->create();
- $comment_id = self::factory()->comment->create(
- array(
- 'comment_post_ID' => $post_id,
- 'comment_approved' => '1',
- )
- );
-
- $table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
- $table->prepare_items();
-
- ob_start();
- $table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringContainsString( 'id="filter-by-comment-type"', $output );
- $this->assertStringContainsString( "<option value='comment'>", $output );
- }
-
- /**
- * @ticket 38341
- *
- * @covers WP_Posts_List_Table::extra_tablenav
- */
- public function test_empty_trash_button_should_not_be_shown_if_there_are_no_comments() {
- $table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
-
- ob_start();
- $table->extra_tablenav( 'top' );
- $output = ob_get_clean();
-
- $this->assertStringNotContainsString( 'id="delete_all"', $output );
- }
-
- /**
- * @ticket 19278
- *
- * @covers WP_Posts_List_Table::bulk_actions
- */
- public function test_bulk_action_menu_supports_options_and_optgroups() {
- $table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
-
- add_filter(
- 'bulk_actions-edit-comments',
- static function() {
- return array(
- 'delete' => 'Delete',
- 'Change State' => array(
- 'feature' => 'Featured',
- 'sale' => 'On Sale',
- ),
- );
- }
- );
-
- ob_start();
- $table->bulk_actions();
- $output = ob_get_clean();
-
- $expected = <<<'OPTIONS'
-<option value="delete">Delete</option>
- <optgroup label="Change State">
- <option value="feature">Featured</option>
- <option value="sale">On Sale</option>
- </optgroup>
-OPTIONS;
- $expected = str_replace( "\r\n", "\n", $expected );
-
- $this->assertStringContainsString( $expected, $output );
- }
-
- /**
- * @ticket 45089
- *
- * @covers WP_Posts_List_Table::print_column_headers
- */
- public function test_sortable_columns() {
- require_once ABSPATH . 'wp-admin/includes/class-wp-comments-list-table.php';
-
- $override_sortable_columns = array(
- 'author' => array( 'comment_author', true ),
- 'response' => 'comment_post_ID',
- 'date' => array( 'comment_date', 'dEsC' ), // The ordering support should be case-insensitive.
- );
-
- // Stub the get_sortable_columns() method.
- $object = $this->getMockBuilder( 'WP_Comments_List_Table' )
- ->setConstructorArgs( array( array( 'screen' => 'edit-comments' ) ) )
- ->setMethods( array( 'get_sortable_columns' ) )
- ->getMock();
-
- // Change the null return value of the stubbed get_sortable_columns() method.
- $object->method( 'get_sortable_columns' )
- ->willReturn( $override_sortable_columns );
-
- $output = get_echo( array( $object, 'print_column_headers' ) );
-
- $this->assertStringContainsString( '?orderby=comment_author&order=desc', $output, 'Mismatch of the default link ordering for comment author column. Should be desc.' );
- $this->assertStringContainsString( 'column-author sortable asc', $output, 'Mismatch of CSS classes for the comment author column.' );
-
- $this->assertStringContainsString( '?orderby=comment_post_ID&order=asc', $output, 'Mismatch of the default link ordering for comment response column. Should be asc.' );
- $this->assertStringContainsString( 'column-response sortable desc', $output, 'Mismatch of CSS classes for the comment post ID column.' );
-
- $this->assertStringContainsString( '?orderby=comment_date&order=desc', $output, 'Mismatch of the default link ordering for comment date column. Should be asc.' );
- $this->assertStringContainsString( 'column-date sortable asc', $output, 'Mismatch of CSS classes for the comment date column.' );
- }
-
- /**
- * @ticket 45089
- *
- * @covers WP_Posts_List_Table::print_column_headers
- */
- public function test_sortable_columns_with_current_ordering() {
- require_once ABSPATH . 'wp-admin/includes/class-wp-comments-list-table.php';
-
- $override_sortable_columns = array(
- 'author' => array( 'comment_author', false ),
- 'response' => 'comment_post_ID',
- 'date' => array( 'comment_date', 'asc' ), // We will override this with current ordering.
- );
-
- // Current ordering.
- $_GET['orderby'] = 'comment_date';
- $_GET['order'] = 'desc';
-
- // Stub the get_sortable_columns() method.
- $object = $this->getMockBuilder( 'WP_Comments_List_Table' )
- ->setConstructorArgs( array( array( 'screen' => 'edit-comments' ) ) )
- ->setMethods( array( 'get_sortable_columns' ) )
- ->getMock();
-
- // Change the null return value of the stubbed get_sortable_columns() method.
- $object->method( 'get_sortable_columns' )
- ->willReturn( $override_sortable_columns );
-
- $output = get_echo( array( $object, 'print_column_headers' ) );
-
- $this->assertStringContainsString( '?orderby=comment_author&order=asc', $output, 'Mismatch of the default link ordering for comment author column. Should be asc.' );
- $this->assertStringContainsString( 'column-author sortable desc', $output, 'Mismatch of CSS classes for the comment author column.' );
-
- $this->assertStringContainsString( '?orderby=comment_post_ID&order=asc', $output, 'Mismatch of the default link ordering for comment response column. Should be asc.' );
- $this->assertStringContainsString( 'column-response sortable desc', $output, 'Mismatch of CSS classes for the comment post ID column.' );
-
- $this->assertStringContainsString( '?orderby=comment_date&order=asc', $output, 'Mismatch of the current link ordering for comment date column. Should be asc.' );
- $this->assertStringContainsString( 'column-date sorted desc', $output, 'Mismatch of CSS classes for the comment date column.' );
- }
-
-}
</del></span></pre></div>
<a id="trunktestsphpunittestsadminwpCommentsListTablephpfromrev51995trunktestsphpunittestsadminincludesListTablephp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/admin/wpCommentsListTable.php (from rev 51995, trunk/tests/phpunit/tests/admin/includesListTable.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/admin/wpCommentsListTable.php (rev 0)
+++ trunk/tests/phpunit/tests/admin/wpCommentsListTable.php 2021-11-03 00:48:42 UTC (rev 51997)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,198 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group admin
+ */
+class Tests_Admin_wpCommentsListTable extends WP_UnitTestCase {
+
+ /**
+ * @var WP_Comments_List_Table
+ */
+ protected $table;
+
+ function set_up() {
+ parent::set_up();
+ $this->table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
+ }
+
+ /**
+ * @ticket 40188
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ public function test_filter_button_should_not_be_shown_if_there_are_no_comments() {
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringNotContainsString( 'id="post-query-submit"', $output );
+ }
+
+ /**
+ * @ticket 40188
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ public function test_filter_button_should_be_shown_if_there_are_comments() {
+ $post_id = self::factory()->post->create();
+ $comment_id = self::factory()->comment->create(
+ array(
+ 'comment_post_ID' => $post_id,
+ 'comment_approved' => '1',
+ )
+ );
+
+ $this->table->prepare_items();
+
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringContainsString( 'id="post-query-submit"', $output );
+ }
+
+ /**
+ * @ticket 40188
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ public function test_filter_comment_type_dropdown_should_be_shown_if_there_are_comments() {
+ $post_id = self::factory()->post->create();
+ $comment_id = self::factory()->comment->create(
+ array(
+ 'comment_post_ID' => $post_id,
+ 'comment_approved' => '1',
+ )
+ );
+
+ $this->table->prepare_items();
+
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringContainsString( 'id="filter-by-comment-type"', $output );
+ $this->assertStringContainsString( "<option value='comment'>", $output );
+ }
+
+ /**
+ * @ticket 38341
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ public function test_empty_trash_button_should_not_be_shown_if_there_are_no_comments() {
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringNotContainsString( 'id="delete_all"', $output );
+ }
+
+ /**
+ * @ticket 19278
+ *
+ * @covers WP_Posts_List_Table::bulk_actions
+ */
+ public function test_bulk_action_menu_supports_options_and_optgroups() {
+ add_filter(
+ 'bulk_actions-edit-comments',
+ static function() {
+ return array(
+ 'delete' => 'Delete',
+ 'Change State' => array(
+ 'feature' => 'Featured',
+ 'sale' => 'On Sale',
+ ),
+ );
+ }
+ );
+
+ ob_start();
+ $this->table->bulk_actions();
+ $output = ob_get_clean();
+
+ $expected = <<<'OPTIONS'
+<option value="delete">Delete</option>
+ <optgroup label="Change State">
+ <option value="feature">Featured</option>
+ <option value="sale">On Sale</option>
+ </optgroup>
+OPTIONS;
+ $expected = str_replace( "\r\n", "\n", $expected );
+
+ $this->assertStringContainsString( $expected, $output );
+ }
+
+ /**
+ * @ticket 45089
+ *
+ * @covers WP_Posts_List_Table::print_column_headers
+ */
+ public function test_sortable_columns() {
+ $override_sortable_columns = array(
+ 'author' => array( 'comment_author', true ),
+ 'response' => 'comment_post_ID',
+ 'date' => array( 'comment_date', 'dEsC' ), // The ordering support should be case-insensitive.
+ );
+
+ // Stub the get_sortable_columns() method.
+ $object = $this->getMockBuilder( 'WP_Comments_List_Table' )
+ ->setConstructorArgs( array( array( 'screen' => 'edit-comments' ) ) )
+ ->setMethods( array( 'get_sortable_columns' ) )
+ ->getMock();
+
+ // Change the null return value of the stubbed get_sortable_columns() method.
+ $object->method( 'get_sortable_columns' )
+ ->willReturn( $override_sortable_columns );
+
+ $output = get_echo( array( $object, 'print_column_headers' ) );
+
+ $this->assertStringContainsString( '?orderby=comment_author&order=desc', $output, 'Mismatch of the default link ordering for comment author column. Should be desc.' );
+ $this->assertStringContainsString( 'column-author sortable asc', $output, 'Mismatch of CSS classes for the comment author column.' );
+
+ $this->assertStringContainsString( '?orderby=comment_post_ID&order=asc', $output, 'Mismatch of the default link ordering for comment response column. Should be asc.' );
+ $this->assertStringContainsString( 'column-response sortable desc', $output, 'Mismatch of CSS classes for the comment post ID column.' );
+
+ $this->assertStringContainsString( '?orderby=comment_date&order=desc', $output, 'Mismatch of the default link ordering for comment date column. Should be asc.' );
+ $this->assertStringContainsString( 'column-date sortable asc', $output, 'Mismatch of CSS classes for the comment date column.' );
+ }
+
+ /**
+ * @ticket 45089
+ *
+ * @covers WP_Posts_List_Table::print_column_headers
+ */
+ public function test_sortable_columns_with_current_ordering() {
+ $override_sortable_columns = array(
+ 'author' => array( 'comment_author', false ),
+ 'response' => 'comment_post_ID',
+ 'date' => array( 'comment_date', 'asc' ), // We will override this with current ordering.
+ );
+
+ // Current ordering.
+ $_GET['orderby'] = 'comment_date';
+ $_GET['order'] = 'desc';
+
+ // Stub the get_sortable_columns() method.
+ $object = $this->getMockBuilder( 'WP_Comments_List_Table' )
+ ->setConstructorArgs( array( array( 'screen' => 'edit-comments' ) ) )
+ ->setMethods( array( 'get_sortable_columns' ) )
+ ->getMock();
+
+ // Change the null return value of the stubbed get_sortable_columns() method.
+ $object->method( 'get_sortable_columns' )
+ ->willReturn( $override_sortable_columns );
+
+ $output = get_echo( array( $object, 'print_column_headers' ) );
+
+ $this->assertStringContainsString( '?orderby=comment_author&order=asc', $output, 'Mismatch of the default link ordering for comment author column. Should be asc.' );
+ $this->assertStringContainsString( 'column-author sortable desc', $output, 'Mismatch of CSS classes for the comment author column.' );
+
+ $this->assertStringContainsString( '?orderby=comment_post_ID&order=asc', $output, 'Mismatch of the default link ordering for comment response column. Should be asc.' );
+ $this->assertStringContainsString( 'column-response sortable desc', $output, 'Mismatch of CSS classes for the comment post ID column.' );
+
+ $this->assertStringContainsString( '?orderby=comment_date&order=asc', $output, 'Mismatch of the current link ordering for comment date column. Should be asc.' );
+ $this->assertStringContainsString( 'column-date sorted desc', $output, 'Mismatch of CSS classes for the comment date column.' );
+ }
+
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestsadminwpPostsListTablephpfromrev51996trunktestsphpunittestsadminincludesListTablephp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/admin/wpPostsListTable.php (from rev 51996, trunk/tests/phpunit/tests/admin/includesListTable.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/admin/wpPostsListTable.php (rev 0)
+++ trunk/tests/phpunit/tests/admin/wpPostsListTable.php 2021-11-03 00:48:42 UTC (rev 51997)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,322 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group admin
+ */
+class Tests_Admin_wpPostsListTable extends WP_UnitTestCase {
+ protected static $top = array();
+ protected static $children = array();
+ protected static $grandchildren = array();
+ protected static $post_ids = array();
+
+ /**
+ * @var WP_Posts_List_Table
+ */
+ protected $table;
+
+ function set_up() {
+ parent::set_up();
+ $this->table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => 'edit-page' ) );
+ }
+
+ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
+ // Note that our top/children/grandchildren arrays are 1-indexed.
+
+ // Create top-level pages.
+ $num_posts = 5;
+ foreach ( range( 1, $num_posts ) as $i ) {
+ $p = $factory->post->create_and_get(
+ array(
+ 'post_type' => 'page',
+ 'post_title' => sprintf( 'Top Level Page %d', $i ),
+ )
+ );
+
+ self::$top[ $i ] = $p;
+ self::$post_ids[] = $p->ID;
+ }
+
+ // Create child pages.
+ $num_children = 3;
+ foreach ( self::$top as $top => $top_page ) {
+ foreach ( range( 1, $num_children ) as $i ) {
+ $p = $factory->post->create_and_get(
+ array(
+ 'post_type' => 'page',
+ 'post_parent' => $top_page->ID,
+ 'post_title' => sprintf( 'Child %d', $i ),
+ )
+ );
+
+ self::$children[ $top ][ $i ] = $p;
+ self::$post_ids[] = $p->ID;
+ }
+ }
+
+ // Create grand-child pages for the third and fourth top-level pages.
+ $num_grandchildren = 3;
+ foreach ( range( 3, 4 ) as $top ) {
+ foreach ( self::$children[ $top ] as $child => $child_page ) {
+ foreach ( range( 1, $num_grandchildren ) as $i ) {
+ $p = $factory->post->create_and_get(
+ array(
+ 'post_type' => 'page',
+ 'post_parent' => $child_page->ID,
+ 'post_title' => sprintf( 'Grandchild %d', $i ),
+ )
+ );
+
+ self::$grandchildren[ $top ][ $child ][ $i ] = $p;
+ self::$post_ids[] = $p->ID;
+ }
+ }
+ }
+ }
+
+ /**
+ * @ticket 15459
+ *
+ * @covers WP_Posts_List_Table::display_rows
+ * @covers WP_Posts_List_Table::set_hierarchical_display
+ */
+ function test_list_hierarchical_pages_first_page() {
+ $this->_test_list_hierarchical_page(
+ array(
+ 'paged' => 1,
+ 'posts_per_page' => 2,
+ ),
+ array(
+ self::$top[1]->ID,
+ self::$children[1][1]->ID,
+ )
+ );
+ }
+
+ /**
+ * @ticket 15459
+ *
+ * @covers WP_Posts_List_Table::display_rows
+ * @covers WP_Posts_List_Table::set_hierarchical_display
+ */
+ function test_list_hierarchical_pages_second_page() {
+ $this->_test_list_hierarchical_page(
+ array(
+ 'paged' => 2,
+ 'posts_per_page' => 2,
+ ),
+ array(
+ self::$top[1]->ID,
+ self::$children[1][2]->ID,
+ self::$children[1][3]->ID,
+ )
+ );
+ }
+
+ /**
+ * @ticket 15459
+ *
+ * @covers WP_Posts_List_Table::display_rows
+ * @covers WP_Posts_List_Table::set_hierarchical_display
+ */
+ function test_search_hierarchical_pages_first_page() {
+ $this->_test_list_hierarchical_page(
+ array(
+ 'paged' => 1,
+ 'posts_per_page' => 2,
+ 's' => 'Child',
+ ),
+ array(
+ self::$children[1][1]->ID,
+ self::$children[1][2]->ID,
+ )
+ );
+ }
+
+ /**
+ * @ticket 15459
+ *
+ * @covers WP_Posts_List_Table::display_rows
+ * @covers WP_Posts_List_Table::set_hierarchical_display
+ */
+ function test_search_hierarchical_pages_second_page() {
+ $this->_test_list_hierarchical_page(
+ array(
+ 'paged' => 2,
+ 'posts_per_page' => 2,
+ 's' => 'Top',
+ ),
+ array(
+ self::$top[3]->ID,
+ self::$top[4]->ID,
+ )
+ );
+ }
+
+ /**
+ * @ticket 15459
+ *
+ * @covers WP_Posts_List_Table::display_rows
+ * @covers WP_Posts_List_Table::set_hierarchical_display
+ */
+ function test_grandchildren_hierarchical_pages_first_page() {
+ // Page 6 is the first page with grandchildren.
+ $this->_test_list_hierarchical_page(
+ array(
+ 'paged' => 6,
+ 'posts_per_page' => 2,
+ ),
+ array(
+ self::$top[3]->ID,
+ self::$children[3][1]->ID,
+ self::$grandchildren[3][1][1]->ID,
+ self::$grandchildren[3][1][2]->ID,
+ )
+ );
+ }
+
+ /**
+ * @ticket 15459
+ *
+ * @covers WP_Posts_List_Table::display_rows
+ * @covers WP_Posts_List_Table::set_hierarchical_display
+ */
+ function test_grandchildren_hierarchical_pages_second_page() {
+ // Page 7 is the second page with grandchildren.
+ $this->_test_list_hierarchical_page(
+ array(
+ 'paged' => 7,
+ 'posts_per_page' => 2,
+ ),
+ array(
+ self::$top[3]->ID,
+ self::$children[3][1]->ID,
+ self::$grandchildren[3][1][3]->ID,
+ self::$children[3][2]->ID,
+ )
+ );
+ }
+
+ /**
+ * Helper function to test the output of a page which uses `WP_Posts_List_Table`.
+ *
+ * @param array $args Query args for the list of pages.
+ * @param array $expected_ids Expected IDs of pages returned.
+ */
+ protected function _test_list_hierarchical_page( array $args, array $expected_ids ) {
+ if ( PHP_VERSION_ID >= 80100 ) {
+ /*
+ * For the time being, ignoring PHP 8.1 "null to non-nullable" deprecations coming in
+ * via hooked in filter functions until a more structural solution to the
+ * "missing input validation" conundrum has been architected and implemented.
+ */
+ $this->expectDeprecation();
+ $this->expectDeprecationMessageMatches( '`Passing null to parameter \#[0-9]+ \(\$[^\)]+\) of type [^ ]+ is deprecated`' );
+ }
+
+ $matches = array();
+
+ $_REQUEST['paged'] = $args['paged'];
+ $GLOBALS['per_page'] = $args['posts_per_page'];
+
+ $args = array_merge(
+ array(
+ 'post_type' => 'page',
+ ),
+ $args
+ );
+
+ // Mimic the behaviour of `wp_edit_posts_query()`:
+ if ( ! isset( $args['orderby'] ) ) {
+ $args['orderby'] = 'menu_order title';
+ $args['order'] = 'asc';
+ $args['posts_per_page'] = -1;
+ $args['posts_per_archive_page'] = -1;
+ }
+
+ // Effectively ignore the output until retrieving it later via `getActualOutput()`.
+ $this->expectOutputRegex( '`.`' );
+
+ $pages = new WP_Query( $args );
+
+ $this->table->set_hierarchical_display( true );
+ $this->table->display_rows( $pages->posts );
+ $output = $this->getActualOutput();
+
+ // Clean up.
+ unset( $_REQUEST['paged'] );
+ unset( $GLOBALS['per_page'] );
+
+ preg_match_all( '|<tr[^>]*>|', $output, $matches );
+
+ $this->assertCount( count( $expected_ids ), array_keys( $matches[0] ) );
+
+ foreach ( $expected_ids as $id ) {
+ $this->assertStringContainsString( sprintf( 'id="post-%d"', $id ), $output );
+ }
+ }
+
+ /**
+ * @ticket 37407
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ function test_filter_button_should_not_be_shown_if_there_are_no_posts() {
+ // Set post type to a non-existent one.
+ $this->table->screen->post_type = 'foo';
+
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringNotContainsString( 'id="post-query-submit"', $output );
+ }
+
+ /**
+ * @ticket 37407
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ function test_months_dropdown_should_not_be_shown_if_there_are_no_posts() {
+ // Set post type to a non-existent one.
+ $this->table->screen->post_type = 'foo';
+
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringNotContainsString( 'id="filter-by-date"', $output );
+ }
+
+ /**
+ * @ticket 37407
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ function test_category_dropdown_should_not_be_shown_if_there_are_no_posts() {
+ // Set post type to a non-existent one.
+ $this->table->screen->post_type = 'foo';
+
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringNotContainsString( 'id="cat"', $output );
+ }
+
+ /**
+ * @ticket 38341
+ *
+ * @covers WP_Posts_List_Table::extra_tablenav
+ */
+ public function test_empty_trash_button_should_not_be_shown_if_there_are_no_posts() {
+ // Set post type to a non-existent one.
+ $this->table->screen->post_type = 'foo';
+
+ ob_start();
+ $this->table->extra_tablenav( 'top' );
+ $output = ob_get_clean();
+
+ $this->assertStringNotContainsString( 'id="delete_all"', $output );
+ }
+
+}
</ins></span></pre>
</div>
</div>
</body>
</html>