Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace tool_dataprivacy;
  18  
  19  use data_privacy_testcase;
  20  
  21  defined('MOODLE_INTERNAL') || die();
  22  
  23  require_once ('data_privacy_testcase.php');
  24  
  25  /**
  26   * Expired data requests tests.
  27   *
  28   * @package    tool_dataprivacy
  29   * @copyright  2018 Michael Hawkins
  30   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31   */
  32  class expired_data_requests_test extends data_privacy_testcase {
  33  
  34      /**
  35       * Test tearDown.
  36       */
  37      public function tearDown(): void {
  38          \core_privacy\local\request\writer::reset();
  39      }
  40  
  41      /**
  42       * Test finding and deleting expired data requests
  43       */
  44      public function test_data_request_expiry() {
  45          global $DB;
  46          $this->resetAfterTest();
  47          \core_privacy\local\request\writer::setup_real_writer_instance();
  48  
  49          // Set up test users.
  50          $this->setAdminUser();
  51          $studentuser = $this->getDataGenerator()->create_user();
  52          $studentusercontext = \context_user::instance($studentuser->id);
  53  
  54          $dpouser = $this->getDataGenerator()->create_user();
  55          $this->assign_site_dpo($dpouser);
  56  
  57          // Set site purpose.
  58          $this->create_system_purpose();
  59  
  60          // Set request expiry to 5 minutes.
  61          set_config('privacyrequestexpiry', 300, 'tool_dataprivacy');
  62  
  63          // Create and approve data request.
  64          $this->setUser($studentuser->id);
  65          $datarequest = api::create_data_request($studentuser->id, api::DATAREQUEST_TYPE_EXPORT);
  66          $requestid = $datarequest->get('id');
  67          $this->setAdminUser();
  68          api::approve_data_request($requestid);
  69          $this->setUser();
  70          ob_start();
  71          $this->runAdhocTasks('\tool_dataprivacy\task\process_data_request_task');
  72          ob_end_clean();
  73  
  74          // Confirm approved and exported.
  75          $request = new data_request($requestid);
  76          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
  77          $fileconditions = array(
  78              'userid' => $studentuser->id,
  79              'component' => 'tool_dataprivacy',
  80              'filearea' => 'export',
  81              'itemid' => $requestid,
  82              'contextid' => $studentusercontext->id,
  83          );
  84          $this->assertEquals(2, $DB->count_records('files', $fileconditions));
  85  
  86          // Run expiry deletion - should not affect test export.
  87          $expiredrequests = data_request::get_expired_requests();
  88          $this->assertEquals(0, count($expiredrequests));
  89          data_request::expire($expiredrequests);
  90  
  91          // Confirm test export was not deleted.
  92          $request = new data_request($requestid);
  93          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
  94          $this->assertEquals(2, $DB->count_records('files', $fileconditions));
  95  
  96          // Change request expiry to 1 second and allow it to elapse.
  97          set_config('privacyrequestexpiry', 1, 'tool_dataprivacy');
  98          $this->waitForSecond();
  99  
 100          // Re-run expiry deletion, confirm the request expires and export is deleted.
 101          $expiredrequests = data_request::get_expired_requests();
 102          $this->assertEquals(1, count($expiredrequests));
 103          data_request::expire($expiredrequests);
 104  
 105          $request = new data_request($requestid);
 106          $this->assertEquals(api::DATAREQUEST_STATUS_EXPIRED, $request->get('status'));
 107          $this->assertEquals(0, $DB->count_records('files', $fileconditions));
 108      }
 109  
 110      /**
 111       * Test for \tool_dataprivacy\data_request::is_expired()
 112       * Tests for the expected request status to protect from false positive/negative,
 113       * then tests is_expired() is returning the expected response.
 114       */
 115      public function test_is_expired() {
 116          $this->resetAfterTest();
 117          \core_privacy\local\request\writer::setup_real_writer_instance();
 118  
 119          // Set request expiry beyond this test.
 120          set_config('privacyrequestexpiry', 20, 'tool_dataprivacy');
 121  
 122          $admin = get_admin();
 123          $this->setAdminUser();
 124  
 125          // Set site purpose.
 126          $this->create_system_purpose();
 127  
 128          // Create export request.
 129          $datarequest = api::create_data_request($admin->id, api::DATAREQUEST_TYPE_EXPORT);
 130          $requestid = $datarequest->get('id');
 131  
 132          // Approve the request.
 133          ob_start();
 134          $this->setAdminUser();
 135          api::approve_data_request($requestid);
 136          $this->runAdhocTasks('\tool_dataprivacy\task\process_data_request_task');
 137          ob_end_clean();
 138  
 139          // Test Download ready (not expired) response.
 140          $request = new data_request($requestid);
 141          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
 142          $result = data_request::is_expired($request);
 143          $this->assertFalse($result);
 144  
 145          // Let request expiry time lapse.
 146          set_config('privacyrequestexpiry', 1, 'tool_dataprivacy');
 147          $this->waitForSecond();
 148  
 149          // Test Download ready (time expired) response.
 150          $request = new data_request($requestid);
 151          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
 152          $result = data_request::is_expired($request);
 153          $this->assertTrue($result);
 154  
 155          // Run the expiry task to properly expire the request.
 156          ob_start();
 157          $task = \core\task\manager::get_scheduled_task('\tool_dataprivacy\task\delete_expired_requests');
 158          $task->execute();
 159          ob_end_clean();
 160  
 161          // Test Expired response status response.
 162          $request = new data_request($requestid);
 163          $this->assertEquals(api::DATAREQUEST_STATUS_EXPIRED, $request->get('status'));
 164          $result = data_request::is_expired($request);
 165          $this->assertTrue($result);
 166      }
 167  
 168      /**
 169       * Create a site (system context) purpose and category.
 170       *
 171       * @return  void
 172       */
 173      protected function create_system_purpose() {
 174          $purpose = new purpose(0, (object) [
 175              'name' => 'Test purpose ' . rand(1, 1000),
 176              'retentionperiod' => 'P1D',
 177              'lawfulbases' => 'gdpr_art_6_1_a',
 178          ]);
 179          $purpose->create();
 180  
 181          $cat = new category(0, (object) ['name' => 'Test category']);
 182          $cat->create();
 183  
 184          $record = (object) [
 185              'purposeid'     => $purpose->get('id'),
 186              'categoryid'    => $cat->get('id'),
 187              'contextlevel'  => CONTEXT_SYSTEM,
 188          ];
 189          api::set_contextlevel($record);
 190      }
 191  }