Make WordPress Core

Changeset 50613


Ignore:
Timestamp:
03/29/2021 07:35:36 PM (3 years ago)
Author:
SergeyBiryukov
Message:

Code Modernization: Check if the _export_data_grouped post meta is an array when generating a personal data export file.

This avoids a fatal error on PHP 8 in wp_privacy_generate_personal_data_export_file() if the _export_data_grouped post meta exists but is not an array.

Additionally, refactor unit tests for the function to:

  • Reduce redundant code
  • Switch to data provider
  • Test on the full HTML output instead of select pieces of the output
  • Expand unhappy path coverage

Follow-up to [43012], [44786], [47146], [47278].

Props hellofromTonya, jrf, xknown.
See #51423.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/privacy-tools.php

    r50230 r50613  
    362362        $email_address
    363363    );
    364 
    365     // And now, all the Groups.
    366     $groups = get_post_meta( $request_id, '_export_data_grouped', true );
    367364
    368365    // First, build an "About" group on the fly for this report.
     
    394391    );
    395392
    396     // Merge in the special about group.
    397     $groups = array_merge( array( 'about' => $about_group ), $groups );
    398 
    399     $groups_count = count( $groups );
     393    // And now, all the Groups.
     394    $groups = get_post_meta( $request_id, '_export_data_grouped', true );
     395    if ( is_array( $groups ) ) {
     396        // Merge in the special "About" group.
     397        $groups       = array_merge( array( 'about' => $about_group ), $groups );
     398        $groups_count = count( $groups );
     399    } else {
     400        if ( false !== $groups ) {
     401            _doing_it_wrong(
     402                __FUNCTION__,
     403                /* translators: %s: Post meta key. */
     404                sprintf( __( 'The %s post meta must be an array.' ), '<code>_export_data_grouped</code>' ),
     405                '5.8.0'
     406            );
     407        }
     408
     409        $groups       = null;
     410        $groups_count = 0;
     411    }
    400412
    401413    // Convert the groups to JSON format.
  • trunk/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportFile.php

    r50037 r50613  
    215215
    216216    /**
     217     * @ticket 51423
     218     *
     219     * @dataProvider data_export_data_grouped_invalid_type
     220     *
     221     * @param mixed $groups '_export_data_grouped' post meta value.
     222     */
     223    public function test_doing_it_wrong_for_export_data_grouped_invalid_type( $groups ) {
     224        update_post_meta( self::$export_request_id, '_export_data_grouped', $groups );
     225
     226        $this->setExpectedIncorrectUsage( 'wp_privacy_generate_personal_data_export_file' );
     227
     228        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     229    }
     230
     231    public function data_export_data_grouped_invalid_type() {
     232        return array(
     233            array( 10 ),
     234            array( 'WordPress' ),
     235            array( null ),
     236            array( true ),
     237            array( false ),
     238            array( new stdClass() ),
     239            array( serialize( array( 10, 'WordPress', null, true, false ) ) ),
     240            array(
     241                json_encode(
     242                    array(
     243                        'user' => array(
     244                            'group_label'       => 'User',
     245                            'group_description' => 'User&#8217;s profile data.',
     246                            'items'             => array(
     247                                'user-1' => array(
     248                                    array(
     249                                        'name'  => 'User ID',
     250                                        'value' => 1,
     251                                    ),
     252                                    array(
     253                                        'name'  => 'User Login Name',
     254                                        'value' => 'user_login',
     255                                    ),
     256                                    array(
     257                                        'name'  => 'User Nice Name',
     258                                        'value' => 'User Name',
     259                                    ),
     260                                    array(
     261                                        'name'  => 'User Email',
     262                                        'value' => 'export-requester@example.com',
     263                                    ),
     264                                    array(
     265                                        'name'  => 'User Registration Date',
     266                                        'value' => '2020-01-31 19:29:29',
     267                                    ),
     268                                    array(
     269                                        'name'  => 'User Display Name',
     270                                        'value' => 'User Name',
     271                                    ),
     272                                    array(
     273                                        'name'  => 'User Nickname',
     274                                        'value' => 'User',
     275                                    ),
     276                                ),
     277                            ),
     278                        ),
     279                    )
     280                ),
     281            ),
     282        );
     283    }
     284
     285    /**
    217286     * Test that an index.php file can be added to the export directory.
    218287     *
     
    241310     *
    242311     * @ticket 44233
    243      */
    244     public function test_html_contents() {
     312     * @ticket 46894
     313     * @ticket 51423
     314     *
     315     * @dataProvider data_contents
     316     *
     317     * @param mixed    $groups           '_export_data_grouped' post meta value.
     318     * @param string[] $expected_content Optional. Expected content. Use "html" key for this test.
     319     */
     320    public function test_html_contents( $groups, array $expected_content = array() ) {
     321        // Set the _doing_it_wrong assertion.
     322        if ( ! is_array( $groups ) ) {
     323            $this->setExpectedIncorrectUsage( 'wp_privacy_generate_personal_data_export_file' );
     324        }
     325
     326        $request    = wp_get_user_request( self::$export_request_id );
     327        $report_dir = $this->setup_export_contents_test( $groups );
     328
     329        $this->assertFileExists( $report_dir . 'index.html' );
     330        $actual_contents = file_get_contents( $report_dir . 'index.html' );
     331
     332        $expected  = "<!DOCTYPE html>\n";
     333        $expected .= "<html>\n";
     334        $expected .= "<head>\n";
     335        $expected .= "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />\n";
     336        $expected .= "<style type='text/css'>body { color: black; font-family: Arial, sans-serif; font-size: 11pt; margin: 15px auto; width: 860px; }table { background: #f0f0f0; border: 1px solid #ddd; margin-bottom: 20px; width: 100%; }th { padding: 5px; text-align: left; width: 20%; }td { padding: 5px; }tr:nth-child(odd) { background-color: #fafafa; }.return-to-top { text-align: right; }</style><title>Personal Data Export for {$request->email}</title></head>\n";
     337        $expected .= "<body>\n";
     338        $expected .= '<h1 id="top">Personal Data Export</h1>';
     339
     340        if ( is_array( $groups ) && isset( $expected_content['html'] ) ) {
     341            $expected .= $this->replace_timestamp_placeholder( $actual_contents, $expected_content['html'] );
     342        }
     343
     344        $expected .= "</body>\n";
     345        $expected .= "</html>\n";
     346
     347        $this->assertSame( $expected, $actual_contents );
     348    }
     349
     350    /**
     351     * Test the export JSON file has all the expected parts.
     352     *
     353     * @ticket 49029
     354     * @ticket 46894
     355     * @ticket 51423
     356     *
     357     * @dataProvider data_contents
     358     *
     359     * @param mixed    $groups           '_export_data_grouped' post meta value.
     360     * @param string[] $expected_content Optional. Expected content. Use "json" key for this test.
     361     */
     362    public function test_json_contents( $groups, array $expected_content = array() ) {
     363        // Set the _doing_it_wrong assertion.
     364        if ( ! is_array( $groups ) ) {
     365            $this->setExpectedIncorrectUsage( 'wp_privacy_generate_personal_data_export_file' );
     366        }
     367
     368        $request    = wp_get_user_request( self::$export_request_id );
     369        $report_dir = $this->setup_export_contents_test( $groups );
     370
     371        $this->assertFileExists( $report_dir . 'index.html' );
     372        $actual_json = file_get_contents( $report_dir . 'export.json' );
     373
     374        $expected = '{"Personal Data Export for ' . $request->email . '":';
     375        if ( ! is_array( $groups ) ) {
     376            $expected .= 'null}';
     377        } else {
     378            // "About" group: to avoid time difference, use the report's "on" timestamp.
     379            $about_group = '{"about":{"group_label":"About","group_description":"Overview of export report.","items":{"about-1":[{"name":"Report generated for","value":"' . $request->email . '"},{"name":"For site","value":"Test Blog"},{"name":"At URL","value":"http:\/\/example.org"},{"name":"On","value":"{{TIMESTAMP}}"}]}}';
     380            $expected   .= $this->replace_timestamp_placeholder( $actual_json, $about_group );
     381            if ( isset( $expected_content['json'] ) ) {
     382                $expected .= $expected_content['json'];
     383            }
     384            $expected .= '}}';
     385        }
     386
     387        $this->assertSame( $expected, $actual_json );
     388    }
     389
     390    private function setup_export_contents_test( $export_data_grouped = null ) {
     391        if ( null === $export_data_grouped ) {
     392            delete_post_meta( self::$export_request_id, '_export_data_grouped' );
     393        } else {
     394            update_post_meta( self::$export_request_id, '_export_data_grouped', $export_data_grouped );
     395        }
     396
    245397        $this->expectOutputString( '' );
     398
    246399        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
    247400        $this->assertTrue( file_exists( $this->export_file_name ) );
     
    256409        $zip->extractTo( $report_dir );
    257410        $zip->close();
    258         $this->assertTrue( file_exists( $report_dir . 'index.html' ) );
    259 
    260         $report_contents = file_get_contents( $report_dir . 'index.html' );
    261         $request         = wp_get_user_request( self::$export_request_id );
    262 
    263         $this->assertContains( '<h1 id="top">Personal Data Export</h1>', $report_contents );
    264         $this->assertContains( '<h2 id="about-about">About</h2>', $report_contents );
    265         $this->assertContains( $request->email, $report_contents );
    266     }
    267 
    268     /**
    269      * Test the export JSON file has all the expected parts.
    270      *
    271      * @ticket 49029
    272      */
    273     public function test_json_contents() {
    274         $this->expectOutputString( '' );
    275         wp_privacy_generate_personal_data_export_file( self::$export_request_id );
    276         $this->assertTrue( file_exists( $this->export_file_name ) );
    277 
    278         $report_dir = trailingslashit( self::$exports_dir . 'test_contents' );
    279         mkdir( $report_dir );
    280 
    281         $zip        = new ZipArchive();
    282         $opened_zip = $zip->open( $this->export_file_name );
    283         $this->assertTrue( $opened_zip );
    284 
    285         $zip->extractTo( $report_dir );
    286         $zip->close();
    287 
    288         $request = wp_get_user_request( self::$export_request_id );
    289 
    290         $this->assertTrue( file_exists( $report_dir . 'export.json' ) );
    291 
    292         $report_contents_json = file_get_contents( $report_dir . 'export.json' );
    293 
    294         $this->assertContains( '"Personal Data Export for ' . $request->email . '"', $report_contents_json );
    295         $this->assertContains( '"about"', $report_contents_json );
    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( 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&#8217;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',
     411
     412        return $report_dir;
     413    }
     414
     415    /**
     416     * Replace expected content's timestamp placeholder with the actual content's timestamp.
     417     *
     418     * Used when the expected content has a placeholder, i.e. used to avoid second time differences
     419     * between the test and code.
     420     *
     421     * @param string $actual_content   Content with the actual timestamp.
     422     * @param string $expected_content Expected content that has the timestamp placeholder
     423     *                                 to be replaced with the actual timestamp.
     424     * @return string Updated expected content on success; else original expected content.
     425     */
     426    private function replace_timestamp_placeholder( $actual_content, $expected_content ) {
     427        $placeholder_pos = stripos( $expected_content, '{{TIMESTAMP}}' );
     428        if ( false === $placeholder_pos ) {
     429            return $expected_content;
     430        }
     431
     432        $needle     = substr( $expected_content, 0, $placeholder_pos );
     433        $needle_pos = strpos( $actual_content, $needle ) + strlen( $needle );
     434        $timestamp  = substr( $actual_content, $needle_pos, 19 );
     435
     436        return str_replace( '{{TIMESTAMP}}', $timestamp, $expected_content );
     437    }
     438
     439    public function data_contents() {
     440        return array(
     441            // Unhappy path.
     442            'should contain null when integer'           => array(
     443                'groups' => 10,
     444            ),
     445            'should contain null when boolean'           => array(
     446                'groups' => true,
     447            ),
     448            'should contain null when string'            => array(
     449                'groups' => 'string',
     450            ),
     451            'should contain null when object'            => array(
     452                'groups' => new stdClass(),
     453            ),
     454            'should contain only about when _export_data_grouped does not exist' => array(
     455                'groups' => null,
     456            ),
     457            'should contain only about when empty array' => array(
     458                'groups'           => array(),
     459                'expected_content' => array(
     460                    'html' => '<h2 id="about-about">About</h2><p>Overview of export report.</p><div><table><tbody><tr><th>Report generated for</th><td>export-requester@example.com</td></tr><tr><th>For site</th><td>Test Blog</td></tr><tr><th>At URL</th><td><a href="http://example.org">http://example.org</a></td></tr><tr><th>On</th><td>{{TIMESTAMP}}</td></tr></tbody></table></div>',
     461                ),
     462            ),
     463            // Happy path.
     464            'should contain about and export data groups when single group exists' => array(
     465                'groups'           => array(
     466                    'user' => array(
     467                        'group_label'       => 'User',
     468                        'group_description' => 'User&#8217;s profile data.',
     469                        'items'             => array(
     470                            'user-1' => array(
     471                                array(
     472                                    'name'  => 'User ID',
     473                                    'value' => 1,
     474                                ),
     475                                array(
     476                                    'name'  => 'User Login Name',
     477                                    'value' => 'user_login',
     478                                ),
     479                                array(
     480                                    'name'  => 'User Nice Name',
     481                                    'value' => 'User Name',
     482                                ),
     483                                array(
     484                                    'name'  => 'User Email',
     485                                    'value' => 'export-requester@example.com',
     486                                ),
     487                                array(
     488                                    'name'  => 'User Registration Date',
     489                                    'value' => '2020-01-31 19:29:29',
     490                                ),
     491                                array(
     492                                    'name'  => 'User Display Name',
     493                                    'value' => 'User Name',
     494                                ),
     495                                array(
     496                                    'name'  => 'User Nickname',
     497                                    'value' => 'User',
     498                                ),
     499                            ),
    369500                        ),
    370501                    ),
    371502                ),
    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( 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&#8217;s profile data.',
    417                 'items'             => array(
    418                     'user-1' => array(
    419                         array(
    420                             'name'  => 'User ID',
    421                             'value' => 1,
     503                'expected_content' => array(
     504                    'html' => '<div id="table_of_contents"><h2>Table of Contents</h2><ul><li><a href="#about-about">About</a></li><li><a href="#user-user">User</a></li></ul></div><h2 id="about-about">About</h2><p>Overview of export report.</p><div><table><tbody><tr><th>Report generated for</th><td>export-requester@example.com</td></tr><tr><th>For site</th><td>Test Blog</td></tr><tr><th>At URL</th><td><a href="http://example.org">http://example.org</a></td></tr><tr><th>On</th><td>{{TIMESTAMP}}</td></tr></tbody></table><div class="return-to-top"><a href="#top"><span aria-hidden="true">&uarr; </span> Go to top</a></div></div><h2 id="user-user">User</h2><p>User&#8217;s profile data.</p><div><table><tbody><tr><th>User ID</th><td>1</td></tr><tr><th>User Login Name</th><td>user_login</td></tr><tr><th>User Nice Name</th><td>User Name</td></tr><tr><th>User Email</th><td>export-requester@example.com</td></tr><tr><th>User Registration Date</th><td>2020-01-31 19:29:29</td></tr><tr><th>User Display Name</th><td>User Name</td></tr><tr><th>User Nickname</th><td>User</td></tr></tbody></table><div class="return-to-top"><a href="#top"><span aria-hidden="true">&uarr; </span> Go to top</a></div></div>',
     505                    'json' => ',"user":{"group_label":"User","group_description":"User&#8217;s profile data.","items":{"user-1":[{"name":"User ID","value":1},{"name":"User Login Name","value":"user_login"},{"name":"User Nice Name","value":"User Name"},{"name":"User Email","value":"export-requester@example.com"},{"name":"User Registration Date","value":"2020-01-31 19:29:29"},{"name":"User Display Name","value":"User Name"},{"name":"User Nickname","value":"User"}]}}',
     506                ),
     507            ),
     508            'should contain about and export data groups when multiple groups exist' => array(
     509                'groups'           => array(
     510                    'user'     => array(
     511                        'group_label'       => 'User',
     512                        'group_description' => 'User&#8217;s profile data.',
     513                        'items'             => array(
     514                            'user-1' => array(
     515                                array(
     516                                    'name'  => 'User ID',
     517                                    'value' => 1,
     518                                ),
     519                                array(
     520                                    'name'  => 'User Login Name',
     521                                    'value' => 'user_login',
     522                                ),
     523                                array(
     524                                    'name'  => 'User Nice Name',
     525                                    'value' => 'User Name',
     526                                ),
     527                                array(
     528                                    'name'  => 'User Email',
     529                                    'value' => 'export-requester@example.com',
     530                                ),
     531                                array(
     532                                    'name'  => 'User Registration Date',
     533                                    'value' => '2020-01-31 19:29:29',
     534                                ),
     535                                array(
     536                                    'name'  => 'User Display Name',
     537                                    'value' => 'User Name',
     538                                ),
     539                                array(
     540                                    'name'  => 'User Nickname',
     541                                    'value' => 'User',
     542                                ),
     543                            ),
    422544                        ),
    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',
     545                    ),
     546                    'comments' => array(
     547                        'group_label'       => 'Comments',
     548                        'group_description' => 'User&#8217;s comment data.',
     549                        'items'             => array(
     550                            'comment-2' => array(
     551                                array(
     552                                    'name'  => 'Comment Author',
     553                                    'value' => 'User Name',
     554                                ),
     555                                array(
     556                                    'name'  => 'Comment Author Email',
     557                                    'value' => 'export-requester@example.com',
     558                                ),
     559                                array(
     560                                    'name'  => 'Comment Author IP',
     561                                    'value' => '::1',
     562                                ),
     563                                array(
     564                                    'name'  => 'Comment Author User Agent',
     565                                    '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',
     566                                ),
     567                                array(
     568                                    'name'  => 'Comment Date',
     569                                    'value' => '2020-01-31 19:55:19',
     570                                ),
     571                                array(
     572                                    'name'  => 'Comment Content',
     573                                    'value' => 'Test',
     574                                ),
     575                                array(
     576                                    'name'  => 'Comment URL',
     577                                    'value' => '<a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-2" target="_blank" rel="noopener">http://localhost:8888/46894/2020/01/31/hello-world/#comment-2</a>',
     578                                ),
     579                            ),
     580                            'comment-3' => array(
     581                                array(
     582                                    'name'  => 'Comment Author',
     583                                    'value' => 'User Name',
     584                                ),
     585                                array(
     586                                    'name'  => 'Comment Author Email',
     587                                    'value' => 'export-requester@example.com',
     588                                ),
     589                                array(
     590                                    'name'  => 'Comment Author IP',
     591                                    'value' => '::1',
     592                                ),
     593                                array(
     594                                    'name'  => 'Comment Author User Agent',
     595                                    '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',
     596                                ),
     597                                array(
     598                                    'name'  => 'Comment Date',
     599                                    'value' => '2020-01-31 20:55:19',
     600                                ),
     601                                array(
     602                                    'name'  => 'Comment Content',
     603                                    'value' => 'Test #2',
     604                                ),
     605                                array(
     606                                    'name'  => 'Comment URL',
     607                                    'value' => '<a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-3" target="_blank" rel="noopener">http://localhost:8888/46894/2020/01/31/hello-world/#comment-3</a>',
     608                                ),
     609                            ),
    446610                        ),
    447611                    ),
    448612                ),
    449             ),
    450             'comments' => array(
    451                 'group_label'       => 'Comments',
    452                 'group_description' => 'User&#8217;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="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="noopener">http://localhost:8888/46894/2020/01/31/hello-world/#comment-3</a>',
    512                         ),
    513                     ),
     613                'expected_content' => array(
     614                    'html' => '<div id="table_of_contents"><h2>Table of Contents</h2><ul><li><a href="#about-about">About</a></li><li><a href="#user-user">User</a></li><li><a href="#comments-comments">Comments <span class="count">(2)</span></a></li></ul></div><h2 id="about-about">About</h2><p>Overview of export report.</p><div><table><tbody><tr><th>Report generated for</th><td>export-requester@example.com</td></tr><tr><th>For site</th><td>Test Blog</td></tr><tr><th>At URL</th><td><a href="http://example.org">http://example.org</a></td></tr><tr><th>On</th><td>{{TIMESTAMP}}</td></tr></tbody></table><div class="return-to-top"><a href="#top"><span aria-hidden="true">&uarr; </span> Go to top</a></div></div><h2 id="user-user">User</h2><p>User&#8217;s profile data.</p><div><table><tbody><tr><th>User ID</th><td>1</td></tr><tr><th>User Login Name</th><td>user_login</td></tr><tr><th>User Nice Name</th><td>User Name</td></tr><tr><th>User Email</th><td>export-requester@example.com</td></tr><tr><th>User Registration Date</th><td>2020-01-31 19:29:29</td></tr><tr><th>User Display Name</th><td>User Name</td></tr><tr><th>User Nickname</th><td>User</td></tr></tbody></table><div class="return-to-top"><a href="#top"><span aria-hidden="true">&uarr; </span> Go to top</a></div></div><h2 id="comments-comments">Comments <span class="count">(2)</span></h2><p>User&#8217;s comment data.</p><div><table><tbody><tr><th>Comment Author</th><td>User Name</td></tr><tr><th>Comment Author Email</th><td>export-requester@example.com</td></tr><tr><th>Comment Author IP</th><td>::1</td></tr><tr><th>Comment Author User Agent</th><td>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</td></tr><tr><th>Comment Date</th><td>2020-01-31 19:55:19</td></tr><tr><th>Comment Content</th><td>Test</td></tr><tr><th>Comment URL</th><td><a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-2">http://localhost:8888/46894/2020/01/31/hello-world/#comment-2</a></td></tr></tbody></table><table><tbody><tr><th>Comment Author</th><td>User Name</td></tr><tr><th>Comment Author Email</th><td>export-requester@example.com</td></tr><tr><th>Comment Author IP</th><td>::1</td></tr><tr><th>Comment Author User Agent</th><td>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</td></tr><tr><th>Comment Date</th><td>2020-01-31 20:55:19</td></tr><tr><th>Comment Content</th><td>Test #2</td></tr><tr><th>Comment URL</th><td><a href="http://localhost:8888/46894/2020/01/31/hello-world/#comment-3">http://localhost:8888/46894/2020/01/31/hello-world/#comment-3</a></td></tr></tbody></table><div class="return-to-top"><a href="#top"><span aria-hidden="true">&uarr; </span> Go to top</a></div></div>',
     615                    'json' => ',"user":{"group_label":"User","group_description":"User&#8217;s profile data.","items":{"user-1":[{"name":"User ID","value":1},{"name":"User Login Name","value":"user_login"},{"name":"User Nice Name","value":"User Name"},{"name":"User Email","value":"export-requester@example.com"},{"name":"User Registration Date","value":"2020-01-31 19:29:29"},{"name":"User Display Name","value":"User Name"},{"name":"User Nickname","value":"User"}]}},"comments":{"group_label":"Comments","group_description":"User&#8217;s comment data.","items":{"comment-2":[{"name":"Comment Author","value":"User Name"},{"name":"Comment Author Email","value":"export-requester@example.com"},{"name":"Comment Author IP","value":"::1"},{"name":"Comment Author User Agent","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"},{"name":"Comment Date","value":"2020-01-31 19:55:19"},{"name":"Comment Content","value":"Test"},{"name":"Comment URL","value":"<a href=\"http:\/\/localhost:8888\/46894\/2020\/01\/31\/hello-world\/#comment-2\" target=\"_blank\" rel=\"noopener\">http:\/\/localhost:8888\/46894\/2020\/01\/31\/hello-world\/#comment-2<\/a>"}],"comment-3":[{"name":"Comment Author","value":"User Name"},{"name":"Comment Author Email","value":"export-requester@example.com"},{"name":"Comment Author IP","value":"::1"},{"name":"Comment Author User Agent","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"},{"name":"Comment Date","value":"2020-01-31 20:55:19"},{"name":"Comment Content","value":"Test #2"},{"name":"Comment URL","value":"<a href=\"http:\/\/localhost:8888\/46894\/2020\/01\/31\/hello-world\/#comment-3\" target=\"_blank\" rel=\"noopener\">http:\/\/localhost:8888\/46894\/2020\/01\/31\/hello-world\/#comment-3<\/a>"}]}}',
    514616                ),
    515617            ),
    516618        );
    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( 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&#8217;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&#8217;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="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( 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 
    656619    }
    657620}
Note: See TracChangeset for help on using the changeset viewer.