Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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  /**
  18   * Expired data requests tests.
  19   *
  20   * @package    tool_dataprivacy
  21   * @copyright  2018 Michael Hawkins
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  use tool_dataprivacy\api;
  26  use tool_dataprivacy\category;
  27  use tool_dataprivacy\data_request;
  28  use tool_dataprivacy\purpose;
  29  
  30  defined('MOODLE_INTERNAL') || die();
  31  global $CFG;
  32  
  33  require_once ('data_privacy_testcase.php');
  34  
  35  /**
  36   * Expired data requests tests.
  37   *
  38   * @package    tool_dataprivacy
  39   * @copyright  2018 Michael Hawkins
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class tool_dataprivacy_expired_data_requests_testcase extends data_privacy_testcase {
  43  
  44      /**
  45       * Test tearDown.
  46       */
  47      public function tearDown(): void {
  48          \core_privacy\local\request\writer::reset();
  49      }
  50  
  51      /**
  52       * Test finding and deleting expired data requests
  53       */
  54      public function test_data_request_expiry() {
  55          global $DB;
  56          $this->resetAfterTest();
  57          \core_privacy\local\request\writer::setup_real_writer_instance();
  58  
  59          // Set up test users.
  60          $this->setAdminUser();
  61          $studentuser = $this->getDataGenerator()->create_user();
  62          $studentusercontext = context_user::instance($studentuser->id);
  63  
  64          $dpouser = $this->getDataGenerator()->create_user();
  65          $this->assign_site_dpo($dpouser);
  66  
  67          // Set site purpose.
  68          $this->create_system_purpose();
  69  
  70          // Set request expiry to 5 minutes.
  71          set_config('privacyrequestexpiry', 300, 'tool_dataprivacy');
  72  
  73          // Create and approve data request.
  74          $this->setUser($studentuser->id);
  75          $datarequest = api::create_data_request($studentuser->id, api::DATAREQUEST_TYPE_EXPORT);
  76          $requestid = $datarequest->get('id');
  77          $this->setAdminUser();
  78          api::approve_data_request($requestid);
  79          $this->setUser();
  80          ob_start();
  81          $this->runAdhocTasks('\tool_dataprivacy\task\process_data_request_task');
  82          ob_end_clean();
  83  
  84          // Confirm approved and exported.
  85          $request = new data_request($requestid);
  86          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
  87          $fileconditions = array(
  88              'userid' => $studentuser->id,
  89              'component' => 'tool_dataprivacy',
  90              'filearea' => 'export',
  91              'itemid' => $requestid,
  92              'contextid' => $studentusercontext->id,
  93          );
  94          $this->assertEquals(2, $DB->count_records('files', $fileconditions));
  95  
  96          // Run expiry deletion - should not affect test export.
  97          $expiredrequests = data_request::get_expired_requests();
  98          $this->assertEquals(0, count($expiredrequests));
  99          data_request::expire($expiredrequests);
 100  
 101          // Confirm test export was not deleted.
 102          $request = new data_request($requestid);
 103          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
 104          $this->assertEquals(2, $DB->count_records('files', $fileconditions));
 105  
 106          // Change request expiry to 1 second and allow it to elapse.
 107          set_config('privacyrequestexpiry', 1, 'tool_dataprivacy');
 108          $this->waitForSecond();
 109  
 110          // Re-run expiry deletion, confirm the request expires and export is deleted.
 111          $expiredrequests = data_request::get_expired_requests();
 112          $this->assertEquals(1, count($expiredrequests));
 113          data_request::expire($expiredrequests);
 114  
 115          $request = new data_request($requestid);
 116          $this->assertEquals(api::DATAREQUEST_STATUS_EXPIRED, $request->get('status'));
 117          $this->assertEquals(0, $DB->count_records('files', $fileconditions));
 118      }
 119  
 120      /**
 121       * Test for \tool_dataprivacy\data_request::is_expired()
 122       * Tests for the expected request status to protect from false positive/negative,
 123       * then tests is_expired() is returning the expected response.
 124       */
 125      public function test_is_expired() {
 126          $this->resetAfterTest();
 127          \core_privacy\local\request\writer::setup_real_writer_instance();
 128  
 129          // Set request expiry beyond this test.
 130          set_config('privacyrequestexpiry', 20, 'tool_dataprivacy');
 131  
 132          $admin = get_admin();
 133          $this->setAdminUser();
 134  
 135          // Set site purpose.
 136          $this->create_system_purpose();
 137  
 138          // Create export request.
 139          $datarequest = api::create_data_request($admin->id, api::DATAREQUEST_TYPE_EXPORT);
 140          $requestid = $datarequest->get('id');
 141  
 142          // Approve the request.
 143          ob_start();
 144          $this->setAdminUser();
 145          api::approve_data_request($requestid);
 146          $this->runAdhocTasks('\tool_dataprivacy\task\process_data_request_task');
 147          ob_end_clean();
 148  
 149          // Test Download ready (not 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->assertFalse($result);
 154  
 155          // Let request expiry time lapse.
 156          set_config('privacyrequestexpiry', 1, 'tool_dataprivacy');
 157          $this->waitForSecond();
 158  
 159          // Test Download ready (time expired) response.
 160          $request = new data_request($requestid);
 161          $this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
 162          $result = data_request::is_expired($request);
 163          $this->assertTrue($result);
 164  
 165          // Run the expiry task to properly expire the request.
 166          ob_start();
 167          $task = \core\task\manager::get_scheduled_task('\tool_dataprivacy\task\delete_expired_requests');
 168          $task->execute();
 169          ob_end_clean();
 170  
 171          // Test Expired response status response.
 172          $request = new data_request($requestid);
 173          $this->assertEquals(api::DATAREQUEST_STATUS_EXPIRED, $request->get('status'));
 174          $result = data_request::is_expired($request);
 175          $this->assertTrue($result);
 176      }
 177  
 178      /**
 179       * Create a site (system context) purpose and category.
 180       *
 181       * @return  void
 182       */
 183      protected function create_system_purpose() {
 184          $purpose = new purpose(0, (object) [
 185              'name' => 'Test purpose ' . rand(1, 1000),
 186              'retentionperiod' => 'P1D',
 187              'lawfulbases' => 'gdpr_art_6_1_a',
 188          ]);
 189          $purpose->create();
 190  
 191          $cat = new category(0, (object) ['name' => 'Test category']);
 192          $cat->create();
 193  
 194          $record = (object) [
 195              'purposeid'     => $purpose->get('id'),
 196              'categoryid'    => $cat->get('id'),
 197              'contextlevel'  => CONTEXT_SYSTEM,
 198          ];
 199          api::set_contextlevel($record);
 200      }
 201  }