Make WordPress Core

Ticket #44233: 44233.diff

File 44233.diff, 30.7 KB (added by desrosj, 7 years ago)
  • tests/phpunit/tests/privacy/wpPrivacyDeleteOldExportFiles.php

     
    143143
    144144                $this->assertTrue( file_exists( self::$index_path ) );
    145145        }
     146
     147        /**
     148         * Test the correct files are deleted when the expiration time is filtered.
     149         */
     150        public function test_filtered_expiration_time() {
     151                add_filter( 'wp_privacy_export_expiration', array( $this, 'filter_export_file_expiration_time' ) );
     152                wp_privacy_delete_old_export_files();
     153
     154                $this->assertTrue( file_exists( self::$active_export_file ) );
     155                $this->assertTrue( file_exists( self::$expired_export_file ) );
     156                remove_filter( 'wp_privacy_export_expiration', array( $this, 'filter_export_file_expiration_time' ) );
     157        }
     158
     159        /**
     160         * Filters the expiration time for export files.
     161         *
     162         * @return int New, longer expiration time.
     163         */
     164        public function filter_export_file_expiration_time() {
     165                return 6 * DAY_IN_SECONDS;
     166        }
    146167}
  • tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportFile.php

     
     1<?php
     2/**
     3 * Define a class to test `wp_privacy_generate_personal_data_export_file()`.
     4 *
     5 * @package WordPress
     6 * @subpackage UnitTests
     7 * @since 4.9.7
     8 */
     9
     10/**
     11 * Test cases for `wp_privacy_generate_personal_data_export_file()`.
     12 *
     13 * @group privacy
     14 * @covers wp_privacy_generate_personal_data_export_file
     15 *
     16 * @since 4.9.7
     17 */
     18class Tests_Privacy_wpPrivacyGeneratePersonalDataExportFile extends WP_UnitTestCase {
     19
     20        /**
     21         * An Export Request ID
     22         *
     23         * @since 4.9.7
     24         *
     25         * @var int $export_request_id
     26         */
     27        protected static $export_request_id;
     28
     29        /**
     30         * Whether an exception has been thrown for the current test method.
     31         *
     32         * Will always be set to false in setUp().
     33         *
     34         * @since 4.9.7
     35         *
     36         * @var bool $exception_was_thrown
     37         */
     38        public $exception_was_thrown = false;
     39
     40        /**
     41         * The full path to the export file for the current test method.
     42         *
     43         * @since 4.9.7
     44         *
     45         * @var string $export_file_name
     46         */
     47        public $export_file_name = '';
     48
     49        /**
     50         * Create fixtures that are shared by multiple test cases.
     51         *
     52         * @since 4.9.7
     53         *
     54         * @param WP_UnitTest_Factory $factory The base factory object.
     55         */
     56        public static function wpSetUpBeforeClass( $factory ) {
     57                self::$export_request_id = wp_create_user_request( 'export-requester@example.com', 'export_personal_data' );
     58                update_post_meta( self::$export_request_id, '_export_data_grouped', array() );
     59        }
     60
     61        /**
     62         * Set up the test fixture.
     63         * Override wp_die(), pretend to be ajax, and suppress E_WARNINGs
     64         *
     65         * @since 4.9.7
     66         */
     67        public function setUp() {
     68                parent::setUp();
     69
     70                if ( ! class_exists( 'ZipArchive' ) ) {
     71                        $this->markTestSkipped( 'The ZipArchive class is missing.' );
     72                }
     73
     74                $this->exception_was_thrown = false;
     75                $this->export_file_name = '';
     76
     77                // We need to override the die handler. Otherwise, the unit tests will die too.
     78                add_filter( 'wp_die_ajax_handler', array( $this, 'get_die_handler' ), 1, 1 );
     79                add_filter( 'wp_doing_ajax', '__return_true' );
     80                add_action( 'wp_privacy_personal_data_export_file_created', array( $this, 'action_wp_privacy_personal_data_export_file_created' ) );
     81
     82                // Suppress warnings from "Cannot modify header information - headers already sent by".
     83                $this->_error_level = error_reporting();
     84                error_reporting( $this->_error_level & ~E_WARNING );
     85
     86                // Delete the wp-personal-data-exports folder before each test.
     87                $wp_privacy_exports_dir = wp_privacy_exports_dir();
     88                if ( empty( $wp_privacy_exports_dir ) ) {
     89                        $this->markTestSkipped( 'Exports directory unclear. Skipping test to avoid loss of data.' );
     90                } else {
     91                        @chmod( $wp_privacy_exports_dir, 0755 );
     92
     93                        if ( ! is_dir( $wp_privacy_exports_dir ) ) {
     94                                wp_delete_file( untrailingslashit( $wp_privacy_exports_dir ) );
     95                        } else {
     96                                if ( 'Windows' === PHP_OS ) {
     97                                        exec( sprintf( "rd /s /q %s", escapeshellarg( $wp_privacy_exports_dir ) ) );
     98                                } else {
     99                                        exec( sprintf( "rm -rf %s", escapeshellarg( $wp_privacy_exports_dir ) ) );
     100                                }
     101                        }
     102                }
     103        }
     104
     105        /**
     106         * Tear down the test fixture.
     107         *
     108         * Remove the wp_die() override, restore error reporting.
     109         *
     110         * @since 4.9.7
     111         */
     112        public function tearDown() {
     113                remove_filter( 'wp_die_ajax_handler', array( $this, 'get_die_handler' ), 1, 1 );
     114                remove_filter( 'wp_doing_ajax', '__return_true' );
     115                remove_action( 'wp_privacy_personal_data_export_file_created', array( $this, 'action_wp_privacy_personal_data_export_file_created' ) );
     116
     117                error_reporting( $this->_error_level );
     118                parent::tearDown();
     119        }
     120
     121        /**
     122         * Return our callback handler.
     123         *
     124         * @since 4.9.7
     125         *
     126         * @return callback
     127         */
     128        public function get_die_handler() {
     129                return array( $this, 'die_handler' );
     130        }
     131
     132        /**
     133         * Handler for wp_die()
     134         * Don't die, throw.
     135         *
     136         * @since 4.9.7
     137         *
     138         * @param string $message (Unfortunately, always empty).
     139         * @throws Exception Throws exception when called.
     140         */
     141        public function die_handler( $message ) {
     142                throw new Exception();
     143        }
     144
     145        /**
     146         * Stores the name of the export zip file to check the file is actually created.
     147         *
     148         * @since 4.9.7
     149         *
     150         * @param string $archive_name Created export zip file path.
     151         */
     152        public function action_wp_privacy_personal_data_export_file_created( $archive_name ) {
     153                $this->export_file_name = $archive_name;
     154        }
     155
     156        /**
     157         * When a remove request ID is passed to the export function an error should be displayed.
     158         *
     159         * @since 4.9.7
     160         */
     161        public function test_wp_privacy_generate_personal_data_export_file_rejects_remove_requests() {
     162                $request_id = wp_create_user_request( 'removal-requester@example.com', 'remove_personal_data' );
     163
     164                try {
     165                        $this->expectOutputString( '{"success":false,"data":"Invalid request ID when generating export file."}' );
     166                        wp_privacy_generate_personal_data_export_file( $request_id );
     167                } catch ( Exception $e ) {
     168                        $this->exception_was_thrown = true;
     169                }
     170
     171                $this->assertTrue( $this->exception_was_thrown );
     172        }
     173
     174        /**
     175         * When an invalid request ID is passed an error should be displayed.
     176         *
     177         * @since 4.9.7
     178         */
     179        public function test_wp_privacy_generate_personal_data_export_file_invalid_request_id() {
     180                try {
     181                        $this->expectOutputString( '{"success":false,"data":"Invalid request ID when generating export file."}' );
     182                        wp_privacy_generate_personal_data_export_file( 123456789 );
     183                } catch ( Exception $e ) {
     184                        $this->exception_was_thrown = true;
     185                }
     186
     187                $this->assertTrue( $this->exception_was_thrown );
     188        }
     189
     190        /**
     191         * When the request post title is not a valid email an error should be displayed.
     192         *
     193         * @since 4.9.7
     194         */
     195        public function test_wp_privacy_generate_personal_data_export_file_rejects_requests_with_bad_email_addresses() {
     196                $request_id = wp_create_user_request( 'bad-email-requester@example.com', 'export_personal_data' );
     197
     198                wp_update_post(
     199                        array(
     200                                'ID'         => $request_id,
     201                                'post_title' => 'not-a-valid-email-address',
     202                        )
     203                );
     204
     205                try {
     206                        $this->expectOutputString( '{"success":false,"data":"Invalid email address when generating export file."}' );
     207                        wp_privacy_generate_personal_data_export_file( $request_id );
     208                } catch ( Exception $e ) {
     209                        $this->exception_was_thrown = true;
     210                }
     211
     212                $this->assertTrue( $this->exception_was_thrown );
     213        }
     214
     215        /**
     216         * When the export directory fails to be created an error should be displayed.
     217         *
     218         * @since 4.9.7
     219         */
     220        public function test_wp_privacy_generate_personal_data_export_file_detects_cannot_create_folder() {
     221                $index_html_path = wp_privacy_exports_dir();
     222                // Create a file with the folder name to ensure the function cannot create a folder.
     223                touch( untrailingslashit( $index_html_path ) );
     224
     225                try {
     226                        $this->expectOutputString( '{"success":false,"data":"Unable to create export folder."}' );
     227                        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     228                } catch ( Exception $e ) {
     229                        $this->exception_was_thrown = true;
     230                }
     231
     232                $this->assertTrue( $this->exception_was_thrown );
     233        }
     234
     235        /**
     236         * When the index.html file cannot be created an error should be displayed.
     237         *
     238         * @since 4.9.7
     239         */
     240        public function test_wp_privacy_generate_personal_data_export_file_detects_cannot_create_index() {
     241                $exports_dir = wp_privacy_exports_dir();
     242
     243                // Create and make the export directory read only so protection will fail.
     244                mkdir( $exports_dir, 0444 );
     245
     246                try {
     247                        $this->expectOutputString( '{"success":false,"data":"Unable to protect export folder from browsing."}' );
     248                        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     249                } catch ( Exception $e ) {
     250                        $this->exception_was_thrown = true;
     251                }
     252
     253                $this->assertTrue( $this->exception_was_thrown );
     254        }
     255
     256        /**
     257         * Test that an index.html file can be added to the export directory.
     258         *
     259         * @since 4.9.7
     260         */
     261        public function test_wp_privacy_generate_personal_data_export_file_creates_index_in_export_folder() {
     262                try {
     263                        $this->expectOutputString( '' );
     264                        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     265                } catch ( Exception $e ) {
     266                        $this->exception_was_thrown = true;
     267                }
     268                $index_html_path = wp_privacy_exports_dir() . 'index.html';
     269
     270                $this->assertFalse( $this->exception_was_thrown );
     271                $this->assertTrue( file_exists( $index_html_path ) );
     272        }
     273
     274        /**
     275         * When the export directory is not writable the report should fail to write.
     276         *
     277         * @since 4.9.7
     278         */
     279        public function test_wp_privacy_generate_personal_data_export_file_detects_cannot_write_html() {
     280                $exports_dir = wp_privacy_exports_dir();
     281                mkdir( $exports_dir );
     282                $index_html_path = wp_privacy_exports_dir() . 'index.html';
     283                touch( $index_html_path );
     284                chmod( $exports_dir, 0555 ); // make the folder read only so html writing will fail.
     285
     286                try {
     287                        $this->expectOutputString( '{"success":false,"data":"Unable to open export file (HTML report) for writing."}' );
     288                        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     289                } catch ( Exception $e ) {
     290                        $this->exception_was_thrown = true;
     291                }
     292
     293                $this->assertTrue( $this->exception_was_thrown );
     294                $this->assertEmpty( $this->export_file_name );
     295        }
     296
     297
     298        /**
     299         * Test that an export file is successfully created.
     300         *
     301         * @since 4.9.7
     302         */
     303        public function test_wp_privacy_generate_personal_data_export_file_can_succeed() {
     304                try {
     305                        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     306                } catch ( Exception $e ) {
     307                        $this->exception_was_thrown = true;
     308                }
     309
     310                $this->assertFalse( $this->exception_was_thrown );
     311                $this->assertTrue( file_exists( $this->export_file_name ) );
     312        }
     313
     314        /**
     315         * Test the export file has all the expected parts.
     316         *
     317         * @since 4.9.7
     318         */
     319        public function test_wp_privacy_generate_personal_data_export_file_contents() {
     320                try {
     321                        $this->expectOutputString( '' );
     322                        wp_privacy_generate_personal_data_export_file( self::$export_request_id );
     323                } catch ( Exception $e ) {
     324                        $this->exception_was_thrown = true;
     325                }
     326
     327                $this->assertFalse( $this->exception_was_thrown );
     328                $this->assertTrue( file_exists( $this->export_file_name ) );
     329
     330                $temp_dir = trailingslashit( wp_privacy_exports_dir() . 'tempdir' );
     331                mkdir( $temp_dir );
     332                $zip = new ZipArchive;
     333                $res = $zip->open( $this->export_file_name );
     334
     335                $this->assertTrue( $res );
     336
     337                $zip->extractTo( $temp_dir );
     338                $zip->close();
     339
     340                $this->assertTrue( file_exists( $temp_dir . 'index.html' ) );
     341
     342                $report_contents = file_get_contents( $temp_dir . 'index.html' );
     343
     344                $this->assertContains( '<h1>Personal Data Export</h1>', $report_contents );
     345                $this->assertContains( '<h2>About</h2>', $report_contents );
     346
     347                $request = wp_get_user_request_data( self::$export_request_id );
     348                $this->assertContains( $request->email, $report_contents );
     349        }
     350}
  • tests/phpunit/tests/privacy/wpPrivacyProcessPersonalDataExportPage.php

     
     1<?php
     2/**
     3 * Test cases for the `wp_privacy_process_personal_data_export_page()` function.
     4 *
     5 * @package WordPress
     6 * @subpackage UnitTests
     7 * @since 4.9.7
     8 */
     9
     10/**
     11 * Tests_Privacy_WpPrivacyProcessPersonalDataExportPage class.
     12 *
     13 * @group privacy
     14 * @covers wp_privacy_process_personal_data_export_page
     15 *
     16 * @since 4.9.7
     17 */
     18class Tests_Privacy_WpPrivacyProcessPersonalDataExportPage extends WP_Ajax_UnitTestCase {
     19        /**
     20         * Request ID.
     21         *
     22         * @since 4.9.7
     23         *
     24         * @var int $request_id
     25         */
     26        protected static $request_id;
     27
     28        /**
     29         * Requester Email.
     30         *
     31         * @since 4.9.7
     32         *
     33         * @var int $request_email
     34         */
     35        protected static $request_email;
     36
     37        /**
     38         * Response for the First Page.
     39         *
     40         * @since 4.9.7
     41         *
     42         * @var array $response
     43         */
     44        protected static $response_first_page;
     45
     46        /**
     47         * Response for the Last Page.
     48         *
     49         * @since 4.9.7
     50         *
     51         * @var array $response_last_page
     52         */
     53        protected static $response_last_page;
     54
     55        /**
     56         * Export File Url.
     57         *
     58         * @since 4.9.7
     59         *
     60         * @var string $export_file_url
     61         */
     62        protected static $export_file_url;
     63
     64        /**
     65         * Requester Email.
     66         *
     67         * @since 4.9.7
     68         *
     69         * @var string $requester_email
     70         */
     71        protected static $requester_email;
     72
     73        /**
     74         * Send As Email.
     75         *
     76         * @since 4.9.7
     77         *
     78         * @var bool $send_as_email
     79         */
     80        protected static $send_as_email;
     81
     82        /**
     83         * Index Of The First Page.
     84         *
     85         * @since 4.9.7
     86         *
     87         * @var int $page
     88         */
     89        protected static $page_index_first;
     90
     91        /**
     92         * Index Of The Last Page.
     93         *
     94         * @since 4.9.7
     95         *
     96         * @var int $page_index_last
     97         */
     98        protected static $page_index_last;
     99
     100        /**
     101         * Index of the First Exporter.
     102         *
     103         * @since 4.9.7
     104         *
     105         * @var int $exporter_index_first
     106         */
     107        protected static $exporter_index_first;
     108
     109        /**
     110         * Index of the Last Exporter.
     111         *
     112         * @since 4.9.7
     113         *
     114         * @var int $exporter_index_last
     115         */
     116        protected static $exporter_index_last;
     117
     118        /**
     119         * Key of the First Exporter.
     120         *
     121         * @since 4.9.7
     122         *
     123         * @var int $exporter_key_first
     124         */
     125        protected static $exporter_key_first;
     126
     127        /**
     128         * Key of the Last Exporter.
     129         *
     130         * @since 4.9.7
     131         *
     132         * @var int $exporter_key_last
     133         */
     134        protected static $exporter_key_last;
     135
     136        /**
     137         * Export data stored on the `wp_privacy_personal_data_export_file` action hook.
     138         *
     139         * @var string $_export_data_grouped_fetched_within_callback
     140         */
     141        public $_export_data_grouped_fetched_within_callback;
     142
     143        /**
     144         * Before each test method.
     145         *
     146         * @since 4.9.7
     147         */
     148        public function setUp() {
     149                parent::setUp();
     150                remove_all_filters( 'wp_privacy_personal_data_exporters' );
     151                remove_all_actions( 'wp_privacy_personal_data_export_file' );
     152                add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_custom_personal_data_exporters' ) );
     153        }
     154
     155        /**
     156         * After each test method.
     157         *
     158         * @since 4.9.7
     159         */
     160        public function tearDown() {
     161                remove_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_custom_personal_data_exporters' ) );
     162                parent::tearDown();
     163        }
     164
     165        /**
     166         * Create user request fixtures shared by test methods.
     167         *
     168         * @since 4.9.7
     169         *
     170         * @param WP_UnitTest_Factory $factory Factory.
     171         */
     172        public static function wpSetUpBeforeClass( $factory ) {
     173                self::$requester_email      = 'requester@example.com';
     174                self::$export_file_url      = wp_privacy_exports_url() . 'wp-personal-data-file-requester-at-example-com-Wv0RfMnGIkl4CFEDEEkSeIdfLmaUrLsl.zip';
     175                $data                       = array(
     176                        array(
     177                                'group_id'    => 'custom-exporter-group-id',
     178                                'group_label' => 'custom-exporter-group-label',
     179                                'item_id'     => 'custom-exporter-item-id',
     180                                'data'        => array(
     181                                        array(
     182                                                'name'  => 'Email',
     183                                                'value' => self::$requester_email,
     184                                        ),
     185                                ),
     186                        ),
     187                );
     188                self::$response_first_page  = array(
     189                        'done' => false,
     190                        'data' => $data,
     191                );
     192                self::$response_last_page   = array(
     193                        'done' => true,
     194                        'data' => $data,
     195                );
     196                self::$request_id           = wp_create_user_request( self::$requester_email, 'export_personal_data' );
     197                self::$send_as_email        = true;
     198                self::$page_index_first     = 1;
     199                self::$page_index_last      = 2;
     200                self::$exporter_index_first = 1;
     201                self::$exporter_index_last  = 2;
     202                self::$exporter_key_first   = 'custom-exporter-first';
     203                self::$exporter_key_last    = 'custom-exporter-last';
     204        }
     205
     206        /**
     207         * Register handler for a custom personal data exporter.
     208         *
     209         * @since 4.9.7
     210         *
     211         * @param  array $exporters An array of personal data exporters.
     212         * @return array $exporters An array of personal data exporters.
     213         */
     214        public function register_custom_personal_data_exporters( $exporters ) {
     215                $exporters[ self::$exporter_key_first ] = array(
     216                        'exporter_friendly_name' => __( 'Custom Exporter #1' ),
     217                        'callback'               => null,
     218                );
     219                $exporters[ self::$exporter_key_last ]  = array(
     220                        'exporter_friendly_name' => __( 'Custom Exporter #2' ),
     221                        'callback'               => null,
     222                );
     223                return $exporters;
     224        }
     225
     226        /**
     227         * The function should return the response when it's not an array.
     228         *
     229         * @since 4.9.7
     230         */
     231        public function test_function_should_return_response_when_response_not_array() {
     232                $response          = 'not-an-array';
     233                $filtered_response = wp_privacy_process_personal_data_export_page(
     234                        $response,
     235                        self::$exporter_index_last,
     236                        self::$requester_email,
     237                        self::$page_index_last,
     238                        self::$request_id,
     239                        self::$send_as_email,
     240                        self::$exporter_key_last
     241                );
     242                $this->assertSame( $response, $filtered_response );
     243        }
     244
     245        /**
     246         * The function should return the response when it's missing the 'done' array key.
     247         *
     248         * @since 4.9.7
     249         */
     250        public function test_function_should_return_response_when_misisng_done_array_key() {
     251                $response          = array(
     252                        'missing-done-array-key' => true,
     253                );
     254                $filtered_response = wp_privacy_process_personal_data_export_page(
     255                        $response,
     256                        self::$exporter_index_last,
     257                        self::$requester_email,
     258                        self::$page_index_last,
     259                        self::$request_id,
     260                        self::$send_as_email,
     261                        self::$exporter_key_last
     262                );
     263                $this->assertSame( $response, $filtered_response );
     264        }
     265
     266        /**
     267         * The function should return the response when it's missing the 'data' array key.
     268         *
     269         * @since 4.9.7
     270         */
     271        public function test_function_should_return_response_when_missing_data_array_key() {
     272                $response          = array(
     273                        'done'                   => true,
     274                        'missing-data-array-key' => true,
     275                );
     276                $filtered_response = wp_privacy_process_personal_data_export_page(
     277                        $response,
     278                        self::$exporter_index_last,
     279                        self::$requester_email,
     280                        self::$page_index_last,
     281                        self::$request_id,
     282                        self::$send_as_email,
     283                        self::$exporter_key_last
     284                );
     285                $this->assertSame( $response, $filtered_response );
     286        }
     287
     288        /**
     289         * The function should return the response when data is not an array
     290         *
     291         * @since 4.9.7
     292         */
     293        public function test_function_should_return_response_when_data_not_array() {
     294                $response          = array(
     295                        'done' => true,
     296                        'data' => 'not-an-array',
     297                );
     298                $filtered_response = wp_privacy_process_personal_data_export_page(
     299                        $response,
     300                        self::$exporter_index_last,
     301                        self::$requester_email,
     302                        self::$page_index_last,
     303                        self::$request_id,
     304                        self::$send_as_email,
     305                        self::$exporter_key_last
     306                );
     307                $this->assertSame( $response, $filtered_response );
     308        }
     309
     310        /**
     311         * The function should error when invalid request ID.
     312         *
     313         * @since 4.9.7
     314         */
     315        public function test_function_should_error_when_invalid_request_id() {
     316                $response   = array(
     317                        'done' => true,
     318                        'data' => array(),
     319                );
     320                $request_id = 0; // Invalid request ID.
     321
     322                ob_start();
     323                try {
     324                        $filtered_response = wp_privacy_process_personal_data_export_page(
     325                                $response,
     326                                self::$exporter_index_last,
     327                                self::$requester_email,
     328                                self::$page_index_last,
     329                                $request_id,
     330                                ! self::$send_as_email,
     331                                self::$exporter_key_last
     332                        );
     333                } catch ( WPAjaxDieContinueException $e ) {
     334                        unset( $e );
     335                }
     336                $filtered_response = json_decode( $this->_last_response );
     337
     338                $this->assertFalse( $filtered_response->success );
     339                $this->assertSame( 'Invalid request ID when merging exporter data.', $filtered_response->data );
     340        }
     341
     342        /**
     343         * The function should error when mail not sent.
     344         *
     345         * @since 4.9.7
     346         */
     347        public function test_function_should_error_when_mail_not_sent() {
     348                ob_start();
     349                add_filter( 'wp_mail_from', '__return_empty_string' ); // Cause `wp_mail()` to return false.
     350                try {
     351                        $filtered_response = wp_privacy_process_personal_data_export_page(
     352                                self::$response_last_page,
     353                                self::$exporter_index_last,
     354                                self::$requester_email,
     355                                self::$page_index_last,
     356                                self::$request_id,
     357                                self::$send_as_email,
     358                                self::$exporter_key_last
     359                        );
     360                } catch ( WPAjaxDieContinueException $e ) {
     361                        unset( $e );
     362                }
     363                remove_filter( 'wp_mail_from', '__return_empty_string' );
     364                $filtered_response = json_decode( $this->_last_response );
     365
     366                $this->assertFalse( $filtered_response->success );
     367                $this->assertSame( 'Unable to send personal data export email.', $filtered_response->data );
     368        }
     369
     370        /**
     371         * The function should return the response containing the export file url when not sent as email and last
     372         * exporter and last page.
     373         *
     374         * @since 4.9.7
     375         */
     376        public function test_function_should_return_response_with_export_file_url_when_not_send_as_email_and_last_exporter_and_last_page() {
     377                update_post_meta( self::$request_id, '_export_file_url', self::$export_file_url );
     378
     379                $filtered_response = wp_privacy_process_personal_data_export_page(
     380                        self::$response_last_page,
     381                        self::$exporter_index_last,
     382                        self::$requester_email,
     383                        self::$page_index_last,
     384                        self::$request_id,
     385                        ! self::$send_as_email,
     386                        self::$exporter_key_last
     387                );
     388
     389                $this->assertArrayHasKey( 'url', $filtered_response );
     390                $this->assertSame( self::$export_file_url, $filtered_response['url'] );
     391                $this->assertSame( self::$response_last_page['done'], $filtered_response['done'] );
     392                $this->assertSame( self::$response_last_page['data'], $filtered_response['data'] );
     393        }
     394
     395        /**
     396         * The function should return the response containing the export file url when sent as email and last exporter
     397         * and last page.
     398         *
     399         * @since 4.9.7
     400         */
     401        public function test_function_should_return_response_without_export_file_url_when_send_as_email_and_last_exporter_and_last_page() {
     402                update_post_meta( self::$request_id, '_export_file_url', self::$export_file_url );
     403
     404                $filtered_response = wp_privacy_process_personal_data_export_page(
     405                        self::$response_last_page,
     406                        self::$exporter_index_last,
     407                        self::$requester_email,
     408                        self::$page_index_last,
     409                        self::$request_id,
     410                        self::$send_as_email,
     411                        self::$exporter_key_last
     412                );
     413
     414                $this->assertArrayNotHasKey( 'url', $filtered_response );
     415                $this->assertSame( self::$response_last_page['done'], $filtered_response['done'] );
     416                $this->assertSame( self::$response_last_page['data'], $filtered_response['data'] );
     417        }
     418
     419        /**
     420         * The function should mark the request as completed when last exporter, last page.
     421         *
     422         * @since 4.9.7
     423         */
     424        public function test_function_should_mark_request_as_completed_when_last_exporter_and_last_page() {
     425                wp_privacy_process_personal_data_export_page(
     426                        self::$response_last_page,
     427                        self::$exporter_index_last,
     428                        self::$requester_email,
     429                        self::$page_index_last,
     430                        self::$request_id,
     431                        self::$send_as_email,
     432                        self::$exporter_key_last
     433                );
     434                $this->assertSame( 'request-completed', get_post_status( self::$request_id ) );
     435
     436                wp_privacy_process_personal_data_export_page(
     437                        self::$response_last_page,
     438                        self::$exporter_index_last,
     439                        self::$requester_email,
     440                        self::$page_index_last,
     441                        self::$request_id,
     442                        ! self::$send_as_email,
     443                        self::$exporter_key_last
     444                );
     445                $this->assertSame( 'request-completed', get_post_status( self::$request_id ) );
     446        }
     447
     448        /**
     449         * The function should leave the request as pending when not last exporter and not last page.
     450         *
     451         * @since 4.9.7
     452         */
     453        public function test_function_should_leave_request_as_pending_when_not_last_exporter_and_not_last_page() {
     454                wp_privacy_process_personal_data_export_page(
     455                        self::$response_first_page,
     456                        self::$exporter_index_first,
     457                        self::$requester_email,
     458                        self::$page_index_first,
     459                        self::$request_id,
     460                        self::$send_as_email,
     461                        self::$exporter_key_first
     462                );
     463                $this->assertSame( 'request-pending', get_post_status( self::$request_id ) );
     464
     465                wp_privacy_process_personal_data_export_page(
     466                        self::$response_first_page,
     467                        self::$exporter_index_first,
     468                        self::$requester_email,
     469                        self::$page_index_first,
     470                        self::$request_id,
     471                        ! self::$send_as_email,
     472                        self::$exporter_key_first
     473                );
     474                $this->assertSame( 'request-pending', get_post_status( self::$request_id ) );
     475        }
     476
     477        /**
     478         * The function should leave the request as pending when last exporter and not last page.
     479         *
     480         * @since 4.9.7
     481         */
     482        public function test_function_should_leave_request_as_pending_when_last_exporter_and_not_last_page() {
     483                wp_privacy_process_personal_data_export_page(
     484                        self::$response_first_page,
     485                        self::$exporter_index_last,
     486                        self::$requester_email,
     487                        self::$page_index_first,
     488                        self::$request_id,
     489                        self::$send_as_email,
     490                        self::$exporter_key_first
     491                );
     492                $this->assertSame( 'request-pending', get_post_status( self::$request_id ) );
     493
     494                wp_privacy_process_personal_data_export_page(
     495                        self::$response_first_page,
     496                        self::$exporter_index_last,
     497                        self::$requester_email,
     498                        self::$page_index_first,
     499                        self::$request_id,
     500                        ! self::$send_as_email,
     501                        self::$exporter_key_first
     502                );
     503                $this->assertSame( 'request-pending', get_post_status( self::$request_id ) );
     504        }
     505
     506        /**
     507         * The function should leave the request as pending when not last exporter and last page.
     508         *
     509         * @since 4.9.7
     510         */
     511        public function test_function_should_leave_request_as_pending_when_not_last_exporter_and_last_page() {
     512                wp_privacy_process_personal_data_export_page(
     513                        self::$response_first_page,
     514                        self::$exporter_index_last,
     515                        self::$requester_email,
     516                        self::$page_index_first,
     517                        self::$request_id,
     518                        self::$send_as_email,
     519                        self::$exporter_key_first
     520                );
     521                $this->assertSame( 'request-pending', get_post_status( self::$request_id ) );
     522
     523                wp_privacy_process_personal_data_export_page(
     524                        self::$response_first_page,
     525                        self::$exporter_index_last,
     526                        self::$requester_email,
     527                        self::$page_index_first,
     528                        self::$request_id,
     529                        ! self::$send_as_email,
     530                        self::$exporter_key_first
     531                );
     532                $this->assertSame( 'request-pending', get_post_status( self::$request_id ) );
     533        }
     534
     535        /**
     536         * The function should add `_export_data_raw` post meta for the request, when first exporter and first page and
     537         * email is sent.
     538         *
     539         * @since 4.9.7
     540         */
     541        public function test_function_should_add_post_meta_with_raw_data_when_first_exporter_and_first_page_send_email() {
     542                $this->assertEmpty( get_post_meta( self::$request_id, '_export_data_raw', true ) );
     543
     544                // First exporter, first page.
     545                wp_privacy_process_personal_data_export_page(
     546                        self::$response_first_page,
     547                        self::$exporter_index_first,
     548                        self::$requester_email,
     549                        self::$page_index_first,
     550                        self::$request_id,
     551                        self::$send_as_email,
     552                        self::$exporter_key_first
     553                );
     554
     555                $this->assertNotEmpty( get_post_meta( self::$request_id, '_export_data_raw', true ) );
     556
     557                // Last exporter, last page.
     558                wp_privacy_process_personal_data_export_page(
     559                        self::$response_last_page,
     560                        self::$exporter_index_last,
     561                        self::$requester_email,
     562                        self::$page_index_last,
     563                        self::$request_id,
     564                        self::$send_as_email,
     565                        self::$exporter_key_last
     566                );
     567
     568                $this->assertEmpty( get_post_meta( self::$request_id, '_export_data_raw', true ) );
     569        }
     570
     571        /**
     572         * The function should add `_export_data_raw` post meta for the request, when first exporter and first page and
     573         * email is not sent.
     574         *
     575         * @since 4.9.7
     576         */
     577        public function test_function_should_add_post_meta_with_raw_data_when_first_exporter_and_first_page_do_not_send_email() {
     578                $this->assertEmpty( get_post_meta( self::$request_id, '_export_data_raw', true ) );
     579
     580                // First exporter, first page.
     581                wp_privacy_process_personal_data_export_page(
     582                        self::$response_first_page,
     583                        self::$exporter_index_first,
     584                        self::$requester_email,
     585                        self::$page_index_first,
     586                        self::$request_id,
     587                        ! self::$send_as_email,
     588                        self::$exporter_key_first
     589                );
     590
     591                $this->assertNotEmpty( get_post_meta( self::$request_id, '_export_data_raw', true ) );
     592
     593                // Last exporter, last page.
     594                wp_privacy_process_personal_data_export_page(
     595                        self::$response_last_page,
     596                        self::$exporter_index_last,
     597                        self::$requester_email,
     598                        self::$page_index_last,
     599                        self::$request_id,
     600                        ! self::$send_as_email,
     601                        self::$exporter_key_last
     602                );
     603
     604                $this->assertEmpty( get_post_meta( self::$request_id, '_export_data_raw', true ) );
     605        }
     606
     607        /**
     608         * The function should add `_export_data_grouped` post meta for the request, only available when personal data export file is generated.
     609         *
     610         * @since 4.9.7
     611         */
     612        public function test_function_should_add_post_meta_with_groups_data_only_available_when_export_file_generated() {
     613                // First exporter, first page.
     614                wp_privacy_process_personal_data_export_page(
     615                        self::$response_first_page,
     616                        self::$exporter_index_first,
     617                        self::$requester_email,
     618                        self::$page_index_first,
     619                        self::$request_id,
     620                        self::$send_as_email,
     621                        self::$exporter_key_first
     622                );
     623
     624                $this->assertEmpty( get_post_meta( self::$request_id, '_export_data_grouped', true ) );
     625
     626                // Last exporter, last page.
     627                add_action( 'wp_privacy_personal_data_export_file', array( $this, 'get_export_groups_data' ) );
     628                wp_privacy_process_personal_data_export_page(
     629                        self::$response_last_page,
     630                        self::$exporter_index_last,
     631                        self::$requester_email,
     632                        self::$page_index_last,
     633                        self::$request_id,
     634                        self::$send_as_email,
     635                        self::$exporter_key_last
     636                );
     637                remove_action( 'wp_privacy_personal_data_export_file', array( $this, 'get_export_groups_data' ) );
     638
     639                $this->assertNotEmpty( $this->_export_data_grouped_fetched_within_callback );
     640                $this->assertEmpty( get_post_meta( self::$request_id, '_export_data_grouped', true ) );
     641        }
     642
     643        /**
     644         * A callback for the `wp_privacy_personal_data_export_file` action that stores the `_export_data_grouped` meta
     645         * data locally for testing.
     646         *
     647         * @since 4.9.7
     648         *
     649         * @param int $request_id Request ID.
     650         */
     651        public function get_export_groups_data( $request_id ) {
     652                $this->_export_data_grouped_fetched_within_callback = get_post_meta( $request_id, '_export_data_grouped', true );
     653        }
     654}