Ticket #46894: 46894.8.diff
File 46894.8.diff, 21.4 KB (added by , 5 years ago) |
---|
-
src/wp-admin/includes/privacy-tools.php
diff --git a/src/wp-admin/includes/privacy-tools.php b/src/wp-admin/includes/privacy-tools.php index c871a1a8e5..8b2af0c52e 100644
a b function _wp_personal_data_cleanup_requests() { 215 215 * Generate a single group for the personal data export report. 216 216 * 217 217 * @since 4.9.6 218 * @since 5.4.0 Added $group_id to support the TOC implementation. 218 219 * 219 220 * @param array $group_data { 220 221 * The group data to render. … … function _wp_personal_data_cleanup_requests() { 231 232 * } 232 233 * } 233 234 * } 234 * @return string The HTML for this group and its items. 235 * @param string $group_id The group identifier. 236 * @param int $groups_count The number of all groups 237 * @return string $group_html The HTML for this group and its items. 235 238 */ 236 function wp_privacy_generate_personal_data_export_group_html( $group_data ) { 237 $group_html = '<h2>'; 239 function wp_privacy_generate_personal_data_export_group_html( $group_data, $group_id = '', $groups_count = 1 ) { 240 $group_id_attr = sanitize_title_with_dashes( $group_data['group_label'] . '-' . $group_id ); 241 242 $group_html = '<h2 id="' . esc_attr( $group_id_attr ) . '">'; 238 243 $group_html .= esc_html( $group_data['group_label'] ); 239 244 240 245 $items_count = count( (array) $group_data['items'] ); … … function wp_privacy_generate_personal_data_export_group_html( $group_data ) { 271 276 $group_html .= '</table>'; 272 277 } 273 278 279 if ( 1 < $groups_count ) { 280 $group_html .= '<div class="return_to_top">'; 281 $group_html .= '<a href="#top">' . esc_html__( '↑ Return to top' ) . '</a>'; 282 $group_html .= '</div>'; 283 } 284 274 285 $group_html .= '</div>'; 275 286 276 287 return $group_html; … … function wp_privacy_generate_personal_data_export_file( $request_id ) { 372 383 // Merge in the special about group. 373 384 $groups = array_merge( array( 'about' => $about_group ), $groups ); 374 385 386 $groups_count = count( $groups ); 387 375 388 // Convert the groups to JSON format. 376 389 $groups_json = wp_json_encode( $groups ); 377 390 … … function wp_privacy_generate_personal_data_export_file( $request_id ) { 409 422 fwrite( $file, 'th { padding: 5px; text-align: left; width: 20%; }' ); 410 423 fwrite( $file, 'td { padding: 5px; }' ); 411 424 fwrite( $file, 'tr:nth-child(odd) { background-color: #fafafa; }' ); 425 fwrite( $file, '.return_to_top { text-align:right; }' ); 412 426 fwrite( $file, '</style>' ); 413 427 fwrite( $file, '<title>' ); 414 428 fwrite( $file, esc_html( $title ) ); 415 429 fwrite( $file, '</title>' ); 416 430 fwrite( $file, "</head>\n" ); 417 431 fwrite( $file, "<body>\n" ); 418 fwrite( $file, '<h1>' . esc_html__( 'Personal Data Export' ) . '</h1>' ); 432 fwrite( $file, '<h1 id="top">' . esc_html__( 'Personal Data Export' ) . '</h1>' ); 433 434 // Create TOC. 435 if ( 1 < $groups_count ) { 436 fwrite( $file, '<div id="table_of_contents">' ); 437 fwrite( $file, '<h2>' . esc_html__( 'Table of Contents' ) . '</h2>' ); 438 fwrite( $file, '<ul>' ); 439 foreach ( (array) $groups as $group_id => $group_data ) { 440 $group_label = esc_html( $group_data['group_label'] ); 441 $group_id_attr = sanitize_title_with_dashes( $group_data['group_label'] . '-' . $group_id ); 442 $group_items_count = count( (array) $group_data['items'] ); 443 if ( $group_items_count > 1 ) { 444 $group_label .= sprintf( ' <span class="count">(%d)</span>', $group_items_count ); 445 } 446 fwrite( $file, '<li>' ); 447 fwrite( $file, '<a href="#' . esc_attr( $group_id_attr ) . '">' . $group_label . '</a>' ); 448 fwrite( $file, '</li>' ); 449 } 450 fwrite( $file, '</ul>' ); 451 fwrite( $file, '</div>' ); 452 } 419 453 420 454 // Now, iterate over every group in $groups and have the formatter render it in HTML. 421 455 foreach ( (array) $groups as $group_id => $group_data ) { 422 fwrite( $file, wp_privacy_generate_personal_data_export_group_html( $group_data ) );456 fwrite( $file, wp_privacy_generate_personal_data_export_group_html( $group_data, $group_id, $groups_count ) ); 423 457 } 424 458 425 459 fwrite( $file, "</body>\n" ); -
tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportFile.php
diff --git a/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportFile.php b/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportFile.php index c38007f498..b7d48b3990 100644
a b class Tests_Privacy_WpPrivacyGeneratePersonalDataExportFile extends WP_UnitTestC 260 260 $report_contents = file_get_contents( $report_dir . 'index.html' ); 261 261 $request = wp_get_user_request_data( self::$export_request_id ); 262 262 263 $this->assertContains( '<h1 >Personal Data Export</h1>', $report_contents );264 $this->assertContains( '<h2 >About</h2>', $report_contents );263 $this->assertContains( '<h1 id="top">Personal Data Export</h1>', $report_contents ); 264 $this->assertContains( '<h2 id="about-about">About</h2>', $report_contents ); 265 265 $this->assertContains( $request->email, $report_contents ); 266 266 } 267 267 … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportFile extends WP_UnitTestC 294 294 $this->assertContains( '"Personal Data Export for ' . $request->email . '"', $report_contents_json ); 295 295 $this->assertContains( '"about"', $report_contents_json ); 296 296 } 297 298 /** 299 * Test the export HTML file containing one export group has no table of contents. 300 * 301 * @ticket 46894 302 */ 303 public function test_single_group_export_no_toc_or_return_to_top() { 304 $this->expectOutputString( '' ); 305 wp_privacy_generate_personal_data_export_file( self::$export_request_id ); 306 $this->assertTrue( file_exists( $this->export_file_name ) ); 307 308 $report_dir = trailingslashit( self::$exports_dir . 'test_contents' ); 309 mkdir( $report_dir ); 310 311 $zip = new ZipArchive(); 312 $opened_zip = $zip->open( $this->export_file_name ); 313 $this->assertTrue( $opened_zip ); 314 315 $zip->extractTo( $report_dir ); 316 $zip->close(); 317 $this->assertTrue( file_exists( $report_dir . 'index.html' ) ); 318 319 $report_contents = file_get_contents( $report_dir . 'index.html' ); 320 $request = wp_get_user_request_data( self::$export_request_id ); 321 322 $this->assertNotContains( '<div id="table_of_contents">', $report_contents ); 323 $this->assertNotContains( '<div class="return_to_top">', $report_contents ); 324 $this->assertContains( $request->email, $report_contents ); 325 } 326 327 /** 328 * Test the export HTML file containing ore than one export group has a table of contents. 329 * 330 * @ticket 46894 331 */ 332 public function test_multiple_group_export_has_toc_and_return_to_top() { 333 $this->expectOutputString( '' ); 334 335 // Setup Export Data to contain multiple groups 336 $export_data_grouped = array( 337 'user' => array( 338 'group_label' => 'User', 339 'group_description' => 'User’s profile data.', 340 'items' => array( 341 'user-1' => array( 342 array( 343 'name' => 'User ID', 344 'value' => 1 345 ), 346 array( 347 'name' => 'User Login Name', 348 'value' => 'user_login' 349 ), 350 array( 351 'name' => 'User Nice Name', 352 'value' => 'User Name' 353 ), 354 array( 355 'name' => 'User Email', 356 'value' => 'export-requester@example.com' 357 ), 358 array( 359 'name' => 'User Registration Date', 360 'value' => '2020-01-31 19:29:29' 361 ), 362 array( 363 'name' => 'User Display Name', 364 'value' => 'User Name' 365 ), 366 array( 367 'name' => 'User Nickname', 368 'value' => 'User' 369 ), 370 ), 371 ), 372 ), 373 ); 374 update_post_meta( self::$export_request_id, '_export_data_grouped', $export_data_grouped ); 375 376 // Generate Export File 377 wp_privacy_generate_personal_data_export_file( self::$export_request_id ); 378 $this->assertTrue( file_exists( $this->export_file_name ) ); 379 380 // Cleam-up for subsequent tests 381 update_post_meta( self::$export_request_id, '_export_data_grouped', array() ); 382 383 $report_dir = trailingslashit( self::$exports_dir . 'test_contents' ); 384 mkdir( $report_dir ); 385 386 $zip = new ZipArchive(); 387 $opened_zip = $zip->open( $this->export_file_name ); 388 $this->assertTrue( $opened_zip ); 389 390 $zip->extractTo( $report_dir ); 391 $zip->close(); 392 $this->assertTrue( file_exists( $report_dir . 'index.html' ) ); 393 394 $report_contents = file_get_contents( $report_dir . 'index.html' ); 395 $request = wp_get_user_request_data( self::$export_request_id ); 396 397 $this->assertContains( '<div id="table_of_contents">', $report_contents ); 398 $this->assertContains( '<h2 id="user-user">User</h2>', $report_contents ); 399 $this->assertContains( '<div class="return_to_top">', $report_contents ); 400 $this->assertContains( $request->email, $report_contents ); 401 } 402 403 /** 404 * Test the export HTML file containing multiple export groups with multiple group items 405 * has a table of contents with group count. 406 * 407 * @ticket 46894 408 */ 409 public function test_multiple_group_export_multiple_items_group_count_in_toc() { 410 $this->expectOutputString( '' ); 411 412 // Setup Export Data to contain multiple groups 413 $export_data_grouped = array( 414 'user' => array( 415 'group_label' => 'User', 416 'group_description' => 'User’s profile data.', 417 'items' => array( 418 'user-1' => array( 419 array( 420 'name' => 'User ID', 421 'value' => 1 422 ), 423 array( 424 'name' => 'User Login Name', 425 'value' => 'user_login' 426 ), 427 array( 428 'name' => 'User Nice Name', 429 'value' => 'User Name' 430 ), 431 array( 432 'name' => 'User Email', 433 'value' => 'export-requester@example.com' 434 ), 435 array( 436 'name' => 'User Registration Date', 437 'value' => '2020-01-31 19:29:29' 438 ), 439 array( 440 'name' => 'User Display Name', 441 'value' => 'User Name' 442 ), 443 array( 444 'name' => 'User Nickname', 445 'value' => 'User' 446 ), 447 ), 448 ), 449 ), 450 'comments' => array( 451 'group_label' => 'Comments', 452 'group_description' => 'User’s comment data.', 453 'items' => array( 454 'comment-2' => array( 455 array( 456 'name' => 'Comment Author', 457 'value' => 'User Name' 458 ), 459 array( 460 'name' => 'Comment Author Email', 461 'value' => 'export-requester@example.com' 462 ), 463 array( 464 'name' => 'Comment Author IP', 465 'value' => '::1' 466 ), 467 array( 468 'name' => 'Comment Author User Agent', 469 'value' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' 470 ), 471 array( 472 'name' => 'Comment Date', 473 'value' => '2020-01-31 19:55:19' 474 ), 475 array( 476 'name' => 'Comment Content', 477 'value' => 'Test' 478 ), 479 array( 480 'name' => 'Comment URL', 481 'value' => '<a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-2" target="_blank" rel="noreferrer noopener">http://localhost:8888/46894/2020/01/31/hello-world/#comment-2</a>' 482 ), 483 ), 484 'comment-3' => array( 485 array( 486 'name' => 'Comment Author', 487 'value' => 'User Name' 488 ), 489 array( 490 'name' => 'Comment Author Email', 491 'value' => 'export-requester@example.com' 492 ), 493 array( 494 'name' => 'Comment Author IP', 495 'value' => '::1' 496 ), 497 array( 498 'name' => 'Comment Author User Agent', 499 'value' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' 500 ), 501 array( 502 'name' => 'Comment Date', 503 'value' => '2020-01-31 20:55:19' 504 ), 505 array( 506 'name' => 'Comment Content', 507 'value' => 'Test #2' 508 ), 509 array( 510 'name' => 'Comment URL', 511 'value' => '<a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-3" target="_blank" rel="noreferrer noopener">http://localhost:8888/46894/2020/01/31/hello-world/#comment-3</a>' 512 ), 513 ), 514 ), 515 ), 516 ); 517 update_post_meta( self::$export_request_id, '_export_data_grouped', $export_data_grouped ); 518 519 // Generate Export File 520 wp_privacy_generate_personal_data_export_file( self::$export_request_id ); 521 $this->assertTrue( file_exists( $this->export_file_name ) ); 522 523 // Cleam-up for subsequent tests 524 update_post_meta( self::$export_request_id, '_export_data_grouped', array() ); 525 526 $report_dir = trailingslashit( self::$exports_dir . 'test_contents' ); 527 mkdir( $report_dir ); 528 529 $zip = new ZipArchive(); 530 $opened_zip = $zip->open( $this->export_file_name ); 531 $this->assertTrue( $opened_zip ); 532 533 $zip->extractTo( $report_dir ); 534 $zip->close(); 535 $this->assertTrue( file_exists( $report_dir . 'index.html' ) ); 536 537 $report_contents = file_get_contents( $report_dir . 'index.html' ); 538 $request = wp_get_user_request_data( self::$export_request_id ); 539 540 $this->assertContains( '<div id="table_of_contents">', $report_contents ); 541 $this->assertContains( '<a href="#comments-comments">Comments <span class="count">(2)</span></a>', $report_contents ); 542 $this->assertContains( $request->email, $report_contents ); 543 } 544 545 /** 546 * Test the export HTML file containing multiple export groups with no multiple group items 547 * has a table of contents without group count. 548 * 549 * @ticket 46894 550 */ 551 public function test_multiple_group_export_single_items_no_group_count_in_toc() { 552 $this->expectOutputString( '' ); 553 554 // Setup Export Data to contain multiple groups 555 $export_data_grouped = array( 556 'user' => array( 557 'group_label' => 'User', 558 'group_description' => 'User’s profile data.', 559 'items' => array( 560 'user-1' => array( 561 array( 562 'name' => 'User ID', 563 'value' => 1 564 ), 565 array( 566 'name' => 'User Login Name', 567 'value' => 'user_login' 568 ), 569 array( 570 'name' => 'User Nice Name', 571 'value' => 'User Name' 572 ), 573 array( 574 'name' => 'User Email', 575 'value' => 'export-requester@example.com' 576 ), 577 array( 578 'name' => 'User Registration Date', 579 'value' => '2020-01-31 19:29:29' 580 ), 581 array( 582 'name' => 'User Display Name', 583 'value' => 'User Name' 584 ), 585 array( 586 'name' => 'User Nickname', 587 'value' => 'User' 588 ), 589 ), 590 ), 591 ), 592 'comments' => array( 593 'group_label' => 'Comments', 594 'group_description' => 'User’s comment data.', 595 'items' => array( 596 'comment-2' => array( 597 array( 598 'name' => 'Comment Author', 599 'value' => 'User Name' 600 ), 601 array( 602 'name' => 'Comment Author Email', 603 'value' => 'export-requester@example.com' 604 ), 605 array( 606 'name' => 'Comment Author IP', 607 'value' => '::1' 608 ), 609 array( 610 'name' => 'Comment Author User Agent', 611 'value' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' 612 ), 613 array( 614 'name' => 'Comment Date', 615 'value' => '2020-01-31 19:55:19' 616 ), 617 array( 618 'name' => 'Comment Content', 619 'value' => 'Test' 620 ), 621 array( 622 'name' => 'Comment URL', 623 'value' => '<a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-2" target="_blank" rel="noreferrer noopener">http://localhost:8888/46894/2020/01/31/hello-world/#comment-2</a>' 624 ), 625 ), 626 ), 627 ), 628 ); 629 update_post_meta( self::$export_request_id, '_export_data_grouped', $export_data_grouped ); 630 631 // Generate Export File 632 wp_privacy_generate_personal_data_export_file( self::$export_request_id ); 633 $this->assertTrue( file_exists( $this->export_file_name ) ); 634 635 // Cleam-up for subsequent tests 636 update_post_meta( self::$export_request_id, '_export_data_grouped', array() ); 637 638 $report_dir = trailingslashit( self::$exports_dir . 'test_contents' ); 639 mkdir( $report_dir ); 640 641 $zip = new ZipArchive(); 642 $opened_zip = $zip->open( $this->export_file_name ); 643 $this->assertTrue( $opened_zip ); 644 645 $zip->extractTo( $report_dir ); 646 $zip->close(); 647 $this->assertTrue( file_exists( $report_dir . 'index.html' ) ); 648 649 $report_contents = file_get_contents( $report_dir . 'index.html' ); 650 $request = wp_get_user_request_data( self::$export_request_id ); 651 652 $this->assertContains( '<div id="table_of_contents">', $report_contents ); 653 $this->assertNotContains( '<span class="count">', $report_contents ); 654 $this->assertContains( $request->email, $report_contents ); 655 656 } 297 657 } -
tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportGroupHtml.php
diff --git a/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportGroupHtml.php b/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportGroupHtml.php index 688f790e22..de721ab451 100644
a b class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 39 39 ), 40 40 ); 41 41 42 $actual = wp_privacy_generate_personal_data_export_group_html( $data );42 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 43 43 $expected_table_markup = '<table><tbody><tr><th>Field 1 Name</th><td>Field 1 Value</td></tr><tr><th>Field 2 Name</th><td>Field 2 Value</td></tr></tbody></table>'; 44 44 45 $this->assertContains( '<h2 >Test Data Group</h2>', $actual );45 $this->assertContains( '<h2 id="test-data-group-test-data-group">Test Data Group</h2>', $actual ); 46 46 $this->assertContains( $expected_table_markup, $actual ); 47 47 } 48 48 … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 79 79 ), 80 80 ); 81 81 82 $actual = wp_privacy_generate_personal_data_export_group_html( $data );82 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 83 83 84 $this->assertContains( '<h2 >Test Data Group', $actual );84 $this->assertContains( '<h2 id="test-data-group-test-data-group">Test Data Group', $actual ); 85 85 $this->assertContains( '<td>Field 1 Value', $actual ); 86 86 $this->assertContains( '<td>Another Field 1 Value', $actual ); 87 87 $this->assertContains( '<td>Field 2 Value', $actual ); … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 117 117 ), 118 118 ); 119 119 120 $actual = wp_privacy_generate_personal_data_export_group_html( $data );120 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 121 121 122 122 $this->assertContains( '<a href="http://wordpress.org">http://wordpress.org</a>', $actual ); 123 123 $this->assertContains( '<a href="https://wordpress.org">https://wordpress.org</a>', $actual ); … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 131 131 */ 132 132 public function test_group_labels_escaped() { 133 133 $data = array( 134 'group_label' => '<div>Escape HTML in group la vels</div>',134 'group_label' => '<div>Escape HTML in group labels</div>', 135 135 'items' => array(), 136 136 ); 137 137 138 $actual = wp_privacy_generate_personal_data_export_group_html( $data );138 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'escape-html-in-group-labels', 2 ); 139 139 140 $this->assertContains( '<h2 ><div>Escape HTML in group lavels</div></h2>', $actual );140 $this->assertContains( '<h2 id="escape-html-in-group-labels-escape-html-in-group-labels"><div>Escape HTML in group labels</div></h2>', $actual ); 141 141 } 142 142 143 143 /** … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 162 162 ), 163 163 ); 164 164 165 $actual = wp_privacy_generate_personal_data_export_group_html( $data ); 166 165 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 167 166 $this->assertContains( $data['items'][0]['links']['value'], $actual ); 168 167 $this->assertContains( $data['items'][0]['formatting']['value'], $actual ); 169 168 } … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 190 189 ), 191 190 ); 192 191 193 $actual = wp_privacy_generate_personal_data_export_group_html( $data );192 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 194 193 195 194 $this->assertNotContains( $data['items'][0]['scripts']['value'], $actual ); 196 195 $this->assertContains( '<td>Testing that script tags are stripped.</td>', $actual ); … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 223 222 ), 224 223 ); 225 224 226 $actual = wp_privacy_generate_personal_data_export_group_html( $data );225 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 227 226 228 $this->assertContains( '<h2 >Test Data Group', $actual );227 $this->assertContains( '<h2 id="test-data-group-test-data-group">Test Data Group', $actual ); 229 228 $this->assertContains( '<span class="count">(2)</span></h2>', $actual ); 230 229 $this->assertSame( 2, substr_count( $actual, '<table>' ) ); 231 230 } … … class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_Unit 248 247 ), 249 248 ); 250 249 251 $actual = wp_privacy_generate_personal_data_export_group_html( $data );250 $actual = wp_privacy_generate_personal_data_export_group_html( $data, 'test-data-group', 2 ); 252 251 253 $this->assertContains( '<h2 >Test Data Group</h2>', $actual );252 $this->assertContains( '<h2 id="test-data-group-test-data-group">Test Data Group</h2>', $actual ); 254 253 $this->assertNotContains( '<span class="count">', $actual ); 255 254 $this->assertSame( 1, substr_count( $actual, '<table>' ) ); 256 255 }