Changeset 14061
- Timestamp:
- 09/18/2024 02:32:35 AM (3 months ago)
- Location:
- sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter
- Files:
-
- 1 added
- 6 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/parts/result-set-single.php
r14060 r14061 2 2 use PTR\Display; 3 3 4 echo Display::get_display_css(); ?>4 echo Display::get_display_css(); 5 5 6 <table> 6 foreach ( $revisions as $revision ) : 7 8 $rev_id = (int) ltrim( $revision->post_name, 'r' ); 9 ?> 10 11 <div class="ptr-test-reporter-single-revision"> 12 <a href="<?php echo esc_url( sprintf( 'https://core.trac.wordpress.org/changeset/%d', $rev_id ) ); ?>"> 13 r<?php echo $rev_id; ?> 14 </a>: <?php echo esc_attr( apply_filters( 'the_title', $revision->post_title ) ); ?> 15 </div> 16 17 <table class="ptr-test-reporter-table alignwide"> 7 18 <thead> 8 19 <tr> 9 <th style="width:100px">Revision</th> 10 <th>Host</th> 11 <th>PHP Version</th> 20 <th style="width:100px">Status</th> 21 <th style="width:150px">PHP Version</th> 12 22 <th>Database Version</th> 13 23 </tr> 14 24 </thead> 15 25 <tbody> 16 <?php 17 $total_cols = 5; 18 foreach ( $revisions as $revision ) : 19 $rev_id = (int) ltrim( $revision->post_name, 'r' ); 20 ?> 21 <tr> 22 <th colspan="<?php echo (int) $total_cols; ?>"><a href="<?php echo esc_url( sprintf( 'https://core.trac.wordpress.org/changeset/%d', $rev_id ) ); ?>">r<?php echo (int) $rev_id; ?></a>: <?php echo wp_kses_post( apply_filters( 'the_title', $revision->post_title ) ); ?></th> 23 </tr> 26 24 27 <?php 25 $query_args 28 $query_args = array( 26 29 'posts_per_page' => $posts_per_page, 30 'author' => $post_author ?? null, 27 31 'post_type' => 'result', 28 32 'post_parent' => $revision->ID, 29 'orderby' => 'post_title', 30 'order' => 'ASC', 33 'orderby' => [ 'author' => 'ASC', 'env_name_clause' => 'ASC' ], 34 'meta_query' => array( 35 'relation' => 'OR', 36 'env_name_clause' => array( 37 'key' => 'environment_name', 38 'compare' => 'EXISTS', 39 ), 40 array( 41 'key' => 'environment_name', 42 'compare' => 'NOT EXISTS', 43 ) 44 ), 31 45 ); 32 46 $report_query = new WP_Query( $query_args ); 33 47 if ( ! empty( $report_query->posts ) ) : 48 49 $prev_author = null; 50 34 51 foreach ( $report_query->posts as $report ) : 35 52 $status = 'Errored'; … … 56 73 ) 57 74 ); 58 if ( ! empty( $user->user_url ) ) { 59 $host .= '</a>'; 60 } 61 if ( ! empty( $user->user_url ) ) { 62 $host .= '<a target="_blank" rel="nofollow" href="' . esc_url( $user->user_url ) . '">'; 63 } 64 $host .= $user->display_name; 75 76 $host .= Display::get_display_reporter_name( $report->post_author ); 77 65 78 if ( ! empty( $user->user_url ) ) { 66 79 $host .= '</a>'; … … 68 81 } 69 82 ?> 83 <?php if ( $prev_author !== $host ): ?> 84 <tr> 85 <td colspan="3"> 86 <?php echo wp_kses_post( $host ); ?> 87 </td> 88 </tr> 89 90 <?php endif; ?> 70 91 <tr> 71 <td><a href="<?php echo esc_url( get_permalink( $report->ID ) ); ?>" title="<?php echo esc_attr( $status_title ); ?>" class="<?php echo esc_attr( 'ptr-status-badge ptr-status-badge-' . strtolower( $status ) ); ?>"><?php echo esc_html( $status ); ?></a></td> 72 <td><?php echo wp_kses_post( $host ); ?></td> 92 <td> 93 <a href="<?php echo esc_url( get_permalink( $report->ID ) ); ?>" title="<?php echo esc_attr( $status_title ); ?>" class="<?php echo esc_attr( 'ptr-status-badge ptr-status-badge-' . strtolower( $status ) ); ?>"> 94 <?php echo esc_html( $status ); ?> 95 </a> 96 </td> 73 97 <td><?php echo esc_html( Display::get_display_php_version( $report->ID ) ); ?></td> 74 98 <td><?php echo esc_html( Display::get_display_mysql_version( $report->ID ) ); ?></td> 75 99 </tr> 76 100 <?php 101 $prev_author = $host; 77 102 endforeach; 78 103 else : 79 104 ?> 80 105 <tr> 81 <td></td> 82 <td colspan="<?php echo (int) $total_cols - 1; ?>"> 106 <td colspan="3"> 83 107 No reports for changeset. 84 108 </td> 85 109 </tr> 86 110 <?php endif; ?> 87 <?php endforeach; ?>88 111 </tbody> 89 112 </table> 113 <?php endforeach; -
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/parts/single-result.php
r10346 r14061 25 25 ) 26 26 ); 27 if ( ! empty( $user->user_url ) ) {28 $host .= '</a>';29 }30 if ( ! empty( $user->user_url ) ) {31 $host .= '<a target="_blank" rel="nofollow" href="' . esc_url( $user->user_url ) . '">';32 }33 27 $host .= $user->display_name; 34 28 if ( ! empty( $user->user_url ) ) { … … 54 48 <td><strong>Host</strong></td> 55 49 <td><?php echo wp_kses_post( $host ); ?></td> 50 </tr> 51 <tr> 52 <td><strong>Test Date</strong></td> 53 <td> 54 <?php the_date(); ?> 55 <?php the_time(); ?> 56 </td> 57 </tr> 58 <tr> 59 <td><strong>Execution Time</strong></td> 60 <td> 61 <?php echo esc_html( Display::get_display_time( $report->ID ) ); ?> 62 </td> 63 </tr> 64 <tr> 65 <td><strong>Environment Name</strong></td> 66 <td> 67 <?php echo esc_html( Display::get_display_environment_name( $report->ID ) ); ?> 68 </td> 56 69 </tr> 57 70 <tr> -
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/phpunit-test-reporter.php
r11328 r14061 8 8 * Text Domain: ptr 9 9 * Domain Path: /languages 10 * Version: 0. 1.310 * Version: 0.2.0 11 11 * License: GPL v3 12 12 * … … 30 30 add_action( 'the_content', array( 'PTR\Display', 'filter_the_content' ) ); 31 31 add_action( 'rest_api_init', array( 'PTR\RestAPI', 'register_routes' ) ); 32 33 32 add_action( 'load-edit.php', 'ptr_load_edit_php' ); 34 33 … … 94 93 return ob_get_clean(); 95 94 } 95 96 /** 97 * Counts the number of failing or passing test reports for a revision. 98 * 99 * @param int $revision_parent_id The current revision's post ID. 100 * @param string $status The status term slug to count. 101 * 102 * @return int The number of reports for the given revision. 103 */ 104 function ptr_count_test_results( $revision_parent_id, $status = 'passed' ) { 105 $report_query = new WP_Query( 106 array( 107 'post_type' => 'result', 108 'post_parent' => $revision_parent_id, 109 'fields' => 'ids', 110 'posts_per_page' => 1, 111 'tax_query' => array( 112 array( 113 'taxonomy' => 'report-result', 114 'terms' => $status, 115 'field' => 'slug', 116 ), 117 ) 118 ) 119 ); 120 121 if ( ! $report_query->have_posts() ) { 122 return 0; 123 } 124 125 return $report_query->found_posts; 126 } -
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/readme.txt
r10290 r14061 1 1 === PHPUnit Test Reporter === 2 Contributors: octalmage, danielbachhuber, wpamitkumar, mikeschroder, pfefferle2 Contributors: octalmage, danielbachhuber, wpamitkumar, kirasong, pfefferle, desrosj, crixu 3 3 Tags: phpunit 4 4 Requires at least: 4.7 5 5 Tested up to: 5.5 6 Stable tag: 0. 1.36 Stable tag: 0.2.0 7 7 License: GPLv3 8 8 License URI: http://www.gnu.org/licenses/gpl-3.0.html … … 45 45 * Include errors along with failures on the error report page ([PR](https://github.com/WordPress/phpunit-test-reporter/pull/84)). 46 46 * Change to `integer` built-in type for `commit` field, following updates in WordPress 5.5. 47 48 49 = 0.2.0 (September 17th, 2024) = 50 * Prevent invalid HTML markup on test result pages. 51 * Add a custom Post_List_Table for the results post type that lacks inline edit/quick edit. 52 * Don't use _get_list_table() as that create the object and triggers some queries. Including the file directly works just as well. 53 * Allow for multiple reports per commit for the same test bot. -
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/src/class-content-model.php
r9884 r14061 43 43 ) 44 44 ); 45 46 register_taxonomy( 47 'php-version', 48 array( 'result' ), 49 array( 50 'labels' => array( 51 'name' => __( 'PHP Versions', 'ptr' ), 52 'singular_name' => __( 'PHP Version', 'ptr' ), 53 ), 54 'hierarchical' => false, 55 'public' => false, 56 'show_ui' => true, 57 'show_admin_column' => true, 58 'show_in_nav_menus' => false, 59 'show_tagcloud' => false, 60 'show_in_rest' => true, 61 ) 62 ); 63 64 register_taxonomy( 65 'db-version', 66 array( 'result' ), 67 array( 68 'labels' => array( 69 'name' => __( 'Database Versions', 'ptr' ), 70 'singular_name' => __( 'Database Version', 'ptr' ), 71 ), 72 'hierarchical' => false, 73 'public' => false, 74 'show_ui' => true, 75 'show_admin_column' => true, 76 'show_in_nav_menus' => false, 77 'show_tagcloud' => false, 78 'show_in_rest' => true, 79 ) 80 ); 81 82 register_taxonomy( 83 'report-result', 84 array( 'result' ), 85 array( 86 'labels' => array( 87 'name' => __( 'Result Status', 'ptr' ), 88 'singular_name' => __( 'Result Status', 'ptr' ), 89 ), 90 'hierarchical' => false, 91 'public' => false, 92 'show_ui' => true, 93 'show_admin_column' => true, 94 'show_in_nav_menus' => false, 95 'show_tagcloud' => false, 96 'show_in_rest' => true, 97 ) 98 ); 45 99 } 46 100 -
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/src/class-display.php
r9884 r14061 75 75 } else { 76 76 $content = ptr_get_template_part( 77 'result-set ',77 'result-set-single', 78 78 array( 79 79 'posts_per_page' => 500, … … 93 93 */ 94 94 public static function render_results( $atts ) { 95 96 $output = '';97 $query_args = array(98 'posts_per_page' => 3,95 $current_user = null; 96 $output = ''; 97 $query_args = array( 98 'posts_per_page' => 20, 99 99 'post_type' => 'result', 100 100 'post_parent' => 0, … … 102 102 'order' => 'DESC', 103 103 ); 104 $paged = isset( $_GET['rpage'] ) ? (int) $_GET['rpage'] : 0;104 $paged = isset( $_GET['rpage'] ) ? (int) $_GET['rpage'] : 0; 105 105 if ( $paged ) { 106 106 $query_args['paged'] = $paged; … … 118 118 } 119 119 $output .= self::get_display_css(); 120 if ( $paged <= 1 ) { 120 121 if ($paged <= 1) { 121 122 $output .= self::get_reporter_avatars(); 122 123 } 124 123 125 $output .= ptr_get_template_part( 124 'result-set', 125 array( 126 'posts_per_page' => 50, 127 'revisions' => $rev_query->posts, 128 ) 126 'result-set-all', 127 array( 128 'revisions' => $rev_query->posts, 129 ) 129 130 ); 131 130 132 ob_start(); 131 133 self::pagination( $rev_query ); … … 143 145 ?> 144 146 <style> 145 a.ptr-status-badge { 146 color: #FFF; 147 .ptr-status-badge { 148 color: #fff !important; 149 text-decoration: none !important; 147 150 display: inline-block; 148 151 padding-left: 8px; … … 153 156 font-weight: normal; 154 157 } 155 a.ptr-status-badge-passed {158 .ptr-status-badge-passed { 156 159 background-color: #39BC00; 157 160 } 158 a.ptr-status-badge-failed {161 .ptr-status-badge-failed { 159 162 background-color: #CD543A; 160 163 } 161 a.ptr-status-badge-errored {164 .ptr-status-badge-errored { 162 165 background-color: #909090; 163 166 } … … 170 173 .pagination-centered ul.pagination li { 171 174 display: inline-block; 175 margin: 0 5px; 172 176 } 173 177 .pagination-centered ul.pagination li a { 174 178 cursor: pointer; 179 } 180 .ptr-test-reporter-table th { 181 text-align: center; 182 } 183 .ptr-test-reporter-table td { 184 text-align: center; 185 } 186 .ptr-test-reporter-table td[colspan] { 187 text-align: left; 175 188 } 176 189 .ptr-test-reporter-list { … … 194 207 margin-top: 6px; 195 208 margin-bottom: 6px; 209 text-transform: none; 196 210 } 197 211 .ptr-test-reporter-list.ptr-test-reporter-inactive li h5.avatar-name { … … 239 253 if ( ! empty( $all_time_reporters ) ) { 240 254 $all_time_reporters = array_map( 'intval', $all_time_reporters ); 241 $output .= '<h4>Registered, but no reports in >25 Revisions</h4>' . PHP_EOL;242 255 $users = get_users( 243 256 array( … … 251 264 } 252 265 } 266 if ( ! empty( $users ) ) { 267 $output .= '<h4>Registered, but no reports in >25 Revisions</h4>' . PHP_EOL; 268 } 253 269 $output .= self::get_user_list( $users, 'inactive' ); 254 270 } … … 293 309 return ''; 294 310 } 295 $minutes = floor( ( (int) $results['time'] / 60 )% 60 );296 $seconds = ( int) $results['time'] % 60;311 $minutes = floor( ( (int) ( $results['time'] / 60 ) )% 60 ); 312 $seconds = ( ( (int) $results['time'] ) % 60 ); 297 313 return "{$minutes}m {$seconds}s"; 298 314 } … … 307 323 $php_version = 'Unknown'; 308 324 $env = get_post_meta( $report_id, 'env', true ); 325 309 326 if ( ! empty( $env['php_version'] ) ) { 310 327 $php_version = 'PHP ' . $env['php_version']; … … 326 343 $mysql_version = $bits[0]; 327 344 } 345 328 346 return $mysql_version; 347 } 348 349 /** 350 * Get the environment name for display 351 * 352 * @param integer $report_id Report ID. 353 * @return string 354 */ 355 public static function get_display_environment_name( $report_id ) { 356 $env_name = get_post_meta( $report_id, 'environment_name', true ); 357 358 if ( ! empty( $env_name ) ) { 359 return esc_html( $env_name ); 360 } 361 362 return 'Unknown'; 363 } 364 365 /** 366 * Get the test reporter's display name. 367 * 368 * @param integer $reporter_id Reporter's user ID. 369 * @return string 370 */ 371 public static function get_display_reporter_name( $reporter_id ) { 372 $reporter = new \WP_User( $reporter_id ); 373 374 if ( empty( $reporter->display_name ) ) { 375 return esc_html( $reporter->display_name ); 376 } 377 378 return $reporter->user_nicename; 329 379 } 330 380 -
sites/trunk/wordpress.org/public_html/wp-content/plugins/phpunit-test-reporter/src/class-restapi.php
r10290 r14061 114 114 } 115 115 116 $env = isset( $parameters['env'] ) ? json_decode( $parameters['env'], true ) : array(); 117 118 $php_version = ''; 119 if ( isset( $env['php_version'] ) ) { 120 $parts = explode( '.', $env['php_version'] ); 121 $php_version = $parts[0] . '.' . $parts[1]; 122 } 123 124 $db_version = ! empty( $parameters['mysql_version'] ) ? $parameters['mysql_version'] : 'Unknown'; 125 $env_name = ! empty( $env['label'] ) ? wp_kses( $env['label'], [] ) : ''; 126 116 127 $current_user = wp_get_current_user(); 117 118 $args = array( 128 $tax_query = [ 129 'relation' => 'AND', 130 ]; 131 132 if ( $php_version ) { 133 $tax_query[] = array( 134 'taxonomy' => 'php-version', 135 'terms' => [ $php_version ], 136 'field' => 'name', 137 ); 138 } 139 140 if ( $db_version ) { 141 $tax_query[] = array( 142 'taxonomy' => 'db-version', 143 'terms' => [ $db_version ], 144 'field' => 'name', 145 ); 146 } 147 148 $meta_query = []; 149 150 if ( $env_name ) { 151 $meta_query[] = array( 152 'key' => 'environment_name', 153 'value' => $env_name, 154 ); 155 } 156 157 // Check to see if the test result already exist. 158 $results = get_posts( array( 119 159 'post_parent' => $parent_id, 120 160 'post_type' => 'result', 121 161 'numberposts' => 1, 122 162 'author' => $current_user->ID, 123 );124 125 // Check to see if the test result already exist.126 $results = get_posts( $args ); 163 'tax_query' => $tax_query, 164 'meta_query' => $meta_query, 165 ) ); 166 127 167 if ( $results ) { 128 168 $post_id = $results[0]->ID; 129 169 } else { 130 $results = array( 131 'post_title' => $current_user->user_login . ' - ' . $slug, 170 $post_title = $current_user->user_login . ' - ' . $slug; 171 172 if ( $env_name ) { 173 $post_title .= ' - ' . $env_name; 174 } 175 176 if ( $php_version ) { 177 $post_title .= ' - ' . $php_version; 178 } 179 180 if ( $db_version ) { 181 $post_title .= ' - ' . $db_version; 182 } 183 184 $args = array( 185 'post_title' => $post_title, 132 186 'post_content' => '', 133 187 'post_status' => 'publish', … … 138 192 139 193 // Store the results. 140 $post_id = wp_insert_post( $ results, true );194 $post_id = wp_insert_post( $args, true ); 141 195 } 142 196 … … 145 199 } 146 200 201 wp_set_object_terms( $post_id, array( $php_version ), 'php-version' ); 202 wp_set_object_terms( $post_id, array( $db_version ), 'db-version' ); 203 147 204 $env = isset( $parameters['env'] ) ? json_decode( $parameters['env'], true ) : array(); 148 205 $results = isset( $parameters['results'] ) ? json_decode( $parameters['results'], true ) : array(); … … 150 207 update_post_meta( $post_id, 'env', $env ); 151 208 update_post_meta( $post_id, 'results', $results ); 209 update_post_meta( $post_id, 'environment_name', $env_name ); 210 211 $outcome = 'Unknown'; 212 213 if ( ! empty( $results['failures'] ) ) { 214 $outcome = 'Failed'; 215 } elseif ( ! empty( $results['errors'] ) ) { 216 $outcome = 'Errored'; 217 } else { 218 $outcome = 'Passed'; 219 } 220 221 wp_set_object_terms( $post_id, $outcome, 'report-result' ); 152 222 153 223 self::maybe_send_email_notifications( $parent_id ); … … 167 237 168 238 return $response; 239 } 240 241 private static function get_new_failures( $post_id ) { 242 $p = get_post( $post_id ); 243 $parent_id = $p->post_parent; 244 245 $post_terms = wp_get_object_terms( $post_id, array( 'php-version', 'db-version' ) ); 246 247 if ( is_wp_error( $post_terms ) ) { 248 return []; 249 } 250 251 $tax_query = []; 252 $meta_query = []; 253 254 foreach ( $post_terms as $term ) { 255 if ( 'php-version' === $term['taxonomy'] ) { 256 $tax_query[] = array( 257 'taxonomy' => 'php-version', 258 'terms' => [ $term['term_id'] ], 259 ); 260 } 261 262 if ( 'db-version' === $term['taxonomy'] ) { 263 $tax_query[] = array( 264 'taxonomy' => 'db-version', 265 'terms' => [ $term['term_id'] ], 266 ); 267 } 268 } 269 270 $env_name = get_post_meta( $post_id, 'environment_name', true ); 271 272 if ( ! empty( $env_name ) ) { 273 $meta_query [] = array( 274 'key' => 'environment_name', 275 'value' => $env_name, 276 ); 277 } 278 279 $previous_results = get_posts( array( 280 'post_parent__not_in' => [ $parent_id ], 281 'post_type' => 'result', 282 'numberposts' => 1, 283 'author' => $p->post_author, 284 'tax_query' => $tax_query, 285 'meta_query' => $meta_query, 286 ) ); 287 288 $new_failures = []; 289 $current_failures = self::get_failures( $post_id ); 290 $previous_failures = []; 291 292 if ( ! empty( $previous_results ) ) { 293 $previous_failures = self::get_failures( $previous_results[0]->ID ); 294 } 295 296 // Find new failures that didn't exist in the previous run. 297 298 foreach( $current_failures as $test_suite => $test_cases ) { 299 foreach( $test_cases as $test_case ) { 300 if ( 301 ! isset( $previous_failures[ $test_suite] ) || 302 ! in_array( $test_case, $previous_failures[ $test_suite ] ) 303 ) { 304 $new_failures[] = "$test_suite::$test_case"; 305 } 306 } 307 } 308 309 return $new_failures; 310 } 311 312 private static function get_failures( $post_id ) { 313 $results = get_post_meta( $post_id, 'results', true ); 314 if ( empty( $results['failures'] ) && empty( $results['errors'] ) ) { 315 return []; 316 } 317 318 $failures = []; 319 320 foreach ( $results['testsuites'] as $suite_name => $testsuite ) { 321 $failures[ $suite_name ] = array_keys( $testsuite['testcases'] ); 322 } 323 324 return $failures; 169 325 } 170 326 … … 205 361 continue; 206 362 } 363 207 364 // If the test result is failed and we haven't yet sent an 208 365 // email notification, then let the reporter know. 209 if ( self::is_failed_result( $result ) 210 && ! get_post_meta( $result->ID, 'ptr_reported_failure', true ) ) { 366 if ( 367 self::is_failed_result( $result ) && 368 ! get_post_meta( $result->ID, 'ptr_reported_failure', true ) 369 ) { 370 $new_failures = self::get_new_failures( $result->ID ); 371 372 if ( empty( $new_failures ) ) { 373 continue; 374 } 375 211 376 $user = get_user_by( 'id', $result->post_author ); 212 if ( $user ) { 213 $subject = '[Host Test Results] Test failure for ' . $result->post_name; 214 $body = 'Hi there,' . PHP_EOL . PHP_EOL 215 . "We've detected a WordPress PHPUnit test failure on your hosting environment. Please review when you have a moment: " 216 . get_permalink( $result->ID ) . PHP_EOL . PHP_EOL 217 . 'Thanks,' . PHP_EOL . PHP_EOL 218 . 'WordPress.org Hosting Community'; 219 wp_mail( $user->user_email, $subject, $body ); 220 update_post_meta( $result->ID, 'ptr_reported_failure', true ); 377 if ( ! $user ) { 378 continue; 221 379 } 380 381 $subject = '[Host Test Results] Test failure for ' . $result->post_name; 382 $body = 'Hi there,' . PHP_EOL . PHP_EOL 383 . "We've detected a new WordPress PHPUnit test failure on your hosting environment. Please review when you have a moment: " 384 . get_permalink( $result->ID ) . PHP_EOL . PHP_EOL 385 . 'New failures:' . PHP_EOL . PHP_EOL 386 . implode( PHP_EOL, $new_failures ) . PHP_EOL . PHP_EOL 387 . 'Thanks,' . PHP_EOL . PHP_EOL 388 . 'WordPress.org Hosting Community'; 389 390 wp_mail( $user->user_email, $subject, $body ); 391 update_post_meta( $result->ID, 'ptr_reported_failure', true ); 222 392 } 223 393 } … … 228 398 * Whether or not a given result is a failed result. 229 399 * 230 * @param WP_Post $post Result post object.400 * @param \WP_Post $post Result post object. 231 401 * @return boolean 232 402 */
Note: See TracChangeset
for help on using the changeset viewer.