Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 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 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   * Privacy provider tests.
  19   *
  20   * @package    mod_choice
  21   * @copyright  2018 Jun Pataleta
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  use core_privacy\local\metadata\collection;
  26  use core_privacy\local\request\deletion_criteria;
  27  use mod_choice\privacy\provider;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  /**
  32   * Privacy provider tests class.
  33   *
  34   * @package    mod_choice
  35   * @copyright  2018 Jun Pataleta
  36   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class mod_choice_privacy_provider_testcase extends \core_privacy\tests\provider_testcase {
  39      /** @var stdClass The student object. */
  40      protected $student;
  41  
  42      /** @var stdClass The choice object. */
  43      protected $choice;
  44  
  45      /** @var stdClass The course object. */
  46      protected $course;
  47  
  48      /**
  49       * {@inheritdoc}
  50       */
  51      protected function setUp() {
  52          $this->resetAfterTest();
  53  
  54          global $DB;
  55          $generator = $this->getDataGenerator();
  56          $course = $generator->create_course();
  57          $options = ['fried rice', 'spring rolls', 'sweet and sour pork', 'satay beef', 'gyouza'];
  58          $params = [
  59              'course' => $course->id,
  60              'option' => $options,
  61              'name' => 'First Choice Activity',
  62              'showpreview' => 0
  63          ];
  64  
  65          $plugingenerator = $generator->get_plugin_generator('mod_choice');
  66          // The choice activity the user will answer.
  67          $choice = $plugingenerator->create_instance($params);
  68          // Create another choice activity.
  69          $plugingenerator->create_instance($params);
  70          $cm = get_coursemodule_from_instance('choice', $choice->id);
  71  
  72          // Create a student which will make a choice.
  73          $student = $generator->create_user();
  74          $studentrole = $DB->get_record('role', ['shortname' => 'student']);
  75          $generator->enrol_user($student->id,  $course->id, $studentrole->id);
  76  
  77          $choicewithoptions = choice_get_choice($choice->id);
  78          $optionids = array_keys($choicewithoptions->option);
  79  
  80          choice_user_submit_response($optionids[2], $choice, $student->id, $course, $cm);
  81          $this->student = $student;
  82          $this->choice = $choice;
  83          $this->course = $course;
  84      }
  85  
  86      /**
  87       * Test for provider::get_metadata().
  88       */
  89      public function test_get_metadata() {
  90          $collection = new collection('mod_choice');
  91          $newcollection = provider::get_metadata($collection);
  92          $itemcollection = $newcollection->get_collection();
  93          $this->assertCount(1, $itemcollection);
  94  
  95          $table = reset($itemcollection);
  96          $this->assertEquals('choice_answers', $table->get_name());
  97  
  98          $privacyfields = $table->get_privacy_fields();
  99          $this->assertArrayHasKey('choiceid', $privacyfields);
 100          $this->assertArrayHasKey('optionid', $privacyfields);
 101          $this->assertArrayHasKey('userid', $privacyfields);
 102          $this->assertArrayHasKey('timemodified', $privacyfields);
 103  
 104          $this->assertEquals('privacy:metadata:choice_answers', $table->get_summary());
 105      }
 106  
 107      /**
 108       * Test for provider::get_contexts_for_userid().
 109       */
 110      public function test_get_contexts_for_userid() {
 111          $cm = get_coursemodule_from_instance('choice', $this->choice->id);
 112  
 113          $contextlist = provider::get_contexts_for_userid($this->student->id);
 114          $this->assertCount(1, $contextlist);
 115          $contextforuser = $contextlist->current();
 116          $cmcontext = context_module::instance($cm->id);
 117          $this->assertEquals($cmcontext->id, $contextforuser->id);
 118      }
 119  
 120      /**
 121       * Test for provider::export_user_data().
 122       */
 123      public function test_export_for_context() {
 124          $cm = get_coursemodule_from_instance('choice', $this->choice->id);
 125          $cmcontext = context_module::instance($cm->id);
 126  
 127          // Export all of the data for the context.
 128          $this->export_context_data_for_user($this->student->id, $cmcontext, 'mod_choice');
 129          $writer = \core_privacy\local\request\writer::with_context($cmcontext);
 130          $this->assertTrue($writer->has_any_data());
 131      }
 132  
 133      /**
 134       * Test for provider::delete_data_for_all_users_in_context().
 135       */
 136      public function test_delete_data_for_all_users_in_context() {
 137          global $DB;
 138  
 139          $choice = $this->choice;
 140          $generator = $this->getDataGenerator();
 141          $cm = get_coursemodule_from_instance('choice', $this->choice->id);
 142  
 143          // Create another student who will answer the choice activity.
 144          $student = $generator->create_user();
 145          $studentrole = $DB->get_record('role', ['shortname' => 'student']);
 146          $generator->enrol_user($student->id, $this->course->id, $studentrole->id);
 147  
 148          $choicewithoptions = choice_get_choice($choice->id);
 149          $optionids = array_keys($choicewithoptions->option);
 150  
 151          choice_user_submit_response($optionids[1], $choice, $student->id, $this->course, $cm);
 152  
 153          // Before deletion, we should have 2 responses.
 154          $count = $DB->count_records('choice_answers', ['choiceid' => $choice->id]);
 155          $this->assertEquals(2, $count);
 156  
 157          // Delete data based on context.
 158          $cmcontext = context_module::instance($cm->id);
 159          provider::delete_data_for_all_users_in_context($cmcontext);
 160  
 161          // After deletion, the choice answers for that choice activity should have been deleted.
 162          $count = $DB->count_records('choice_answers', ['choiceid' => $choice->id]);
 163          $this->assertEquals(0, $count);
 164      }
 165  
 166      /**
 167       * Test for provider::delete_data_for_user().
 168       */
 169      public function test_delete_data_for_user_() {
 170          global $DB;
 171  
 172          $choice = $this->choice;
 173          $generator = $this->getDataGenerator();
 174          $cm1 = get_coursemodule_from_instance('choice', $this->choice->id);
 175  
 176          // Create a second choice activity.
 177          $options = ['Boracay', 'Camiguin', 'Bohol', 'Cebu', 'Coron'];
 178          $params = [
 179              'course' => $this->course->id,
 180              'option' => $options,
 181              'name' => 'Which do you think is the best island in the Philippines?',
 182              'showpreview' => 0
 183          ];
 184          $plugingenerator = $generator->get_plugin_generator('mod_choice');
 185          $choice2 = $plugingenerator->create_instance($params);
 186          $plugingenerator->create_instance($params);
 187          $cm2 = get_coursemodule_from_instance('choice', $choice2->id);
 188  
 189          // Make a selection for the first student for the 2nd choice activity.
 190          $choicewithoptions = choice_get_choice($choice2->id);
 191          $optionids = array_keys($choicewithoptions->option);
 192          choice_user_submit_response($optionids[2], $choice2, $this->student->id, $this->course, $cm2);
 193  
 194          // Create another student who will answer the first choice activity.
 195          $otherstudent = $generator->create_user();
 196          $studentrole = $DB->get_record('role', ['shortname' => 'student']);
 197          $generator->enrol_user($otherstudent->id, $this->course->id, $studentrole->id);
 198  
 199          $choicewithoptions = choice_get_choice($choice->id);
 200          $optionids = array_keys($choicewithoptions->option);
 201  
 202          choice_user_submit_response($optionids[1], $choice, $otherstudent->id, $this->course, $cm1);
 203  
 204          // Before deletion, we should have 2 responses.
 205          $count = $DB->count_records('choice_answers', ['choiceid' => $choice->id]);
 206          $this->assertEquals(2, $count);
 207  
 208          $context1 = context_module::instance($cm1->id);
 209          $context2 = context_module::instance($cm2->id);
 210          $contextlist = new \core_privacy\local\request\approved_contextlist($this->student, 'choice',
 211              [context_system::instance()->id, $context1->id, $context2->id]);
 212          provider::delete_data_for_user($contextlist);
 213  
 214          // After deletion, the choice answers for the first student should have been deleted.
 215          $count = $DB->count_records('choice_answers', ['choiceid' => $choice->id, 'userid' => $this->student->id]);
 216          $this->assertEquals(0, $count);
 217  
 218          // Confirm that we only have one choice answer available.
 219          $choiceanswers = $DB->get_records('choice_answers');
 220          $this->assertCount(1, $choiceanswers);
 221          $lastresponse = reset($choiceanswers);
 222          // And that it's the other student's response.
 223          $this->assertEquals($otherstudent->id, $lastresponse->userid);
 224      }
 225  
 226      /**
 227       * Test for provider::get_users_in_context().
 228       */
 229      public function test_get_users_in_context() {
 230          $cm = get_coursemodule_from_instance('choice', $this->choice->id);
 231          $cmcontext = context_module::instance($cm->id);
 232  
 233          $userlist = new \core_privacy\local\request\userlist($cmcontext, 'mod_choice');
 234          \mod_choice\privacy\provider::get_users_in_context($userlist);
 235  
 236          $this->assertEquals(
 237                  [$this->student->id],
 238                  $userlist->get_userids()
 239          );
 240      }
 241  
 242      /**
 243       * Test for provider::get_users_in_context() with invalid context type.
 244       */
 245      public function test_get_users_in_context_invalid_context_type() {
 246          $systemcontext = context_system::instance();
 247  
 248          $userlist = new \core_privacy\local\request\userlist($systemcontext, 'mod_choice');
 249          \mod_choice\privacy\provider::get_users_in_context($userlist);
 250  
 251          $this->assertCount(0, $userlist->get_userids());
 252      }
 253  
 254      /**
 255       * Test for provider::delete_data_for_users().
 256       */
 257      public function test_delete_data_for_users() {
 258          global $DB;
 259  
 260          $choice = $this->choice;
 261          $generator = $this->getDataGenerator();
 262          $cm1 = get_coursemodule_from_instance('choice', $this->choice->id);
 263  
 264          // Create a second choice activity.
 265          $options = ['Boracay', 'Camiguin', 'Bohol', 'Cebu', 'Coron'];
 266          $params = [
 267              'course' => $this->course->id,
 268              'option' => $options,
 269              'name' => 'Which do you think is the best island in the Philippines?',
 270              'showpreview' => 0
 271          ];
 272          $plugingenerator = $generator->get_plugin_generator('mod_choice');
 273          $choice2 = $plugingenerator->create_instance($params);
 274          $plugingenerator->create_instance($params);
 275          $cm2 = get_coursemodule_from_instance('choice', $choice2->id);
 276  
 277          // Make a selection for the first student for the 2nd choice activity.
 278          $choicewithoptions = choice_get_choice($choice2->id);
 279          $optionids = array_keys($choicewithoptions->option);
 280          choice_user_submit_response($optionids[2], $choice2, $this->student->id, $this->course, $cm2);
 281  
 282          // Create 2 other students who will answer the first choice activity.
 283          $otherstudent = $generator->create_and_enrol($this->course, 'student');
 284          $anotherstudent = $generator->create_and_enrol($this->course, 'student');
 285  
 286          $choicewithoptions = choice_get_choice($choice->id);
 287          $optionids = array_keys($choicewithoptions->option);
 288  
 289          choice_user_submit_response($optionids[1], $choice, $otherstudent->id, $this->course, $cm1);
 290          choice_user_submit_response($optionids[1], $choice, $anotherstudent->id, $this->course, $cm1);
 291  
 292          // Before deletion, we should have 3 responses in the first choice activity.
 293          $count = $DB->count_records('choice_answers', ['choiceid' => $choice->id]);
 294          $this->assertEquals(3, $count);
 295  
 296          $context1 = context_module::instance($cm1->id);
 297          $approveduserlist = new \core_privacy\local\request\approved_userlist($context1, 'choice',
 298                  [$this->student->id, $otherstudent->id]);
 299          provider::delete_data_for_users($approveduserlist);
 300  
 301          // After deletion, the choice answers of the 2 students provided above should have been deleted
 302          // from the first choice activity. So there should only remain 1 answer which is for $anotherstudent.
 303          $choiceanswers = $DB->get_records('choice_answers', ['choiceid' => $choice->id]);
 304          $this->assertCount(1, $choiceanswers);
 305          $lastresponse = reset($choiceanswers);
 306          $this->assertEquals($anotherstudent->id, $lastresponse->userid);
 307  
 308          // Confirm that the answer that was submitted in the other choice activity is intact.
 309          $choiceanswers = $DB->get_records_select('choice_answers', 'choiceid <> ?', [$choice->id]);
 310          $this->assertCount(1, $choiceanswers);
 311          $lastresponse = reset($choiceanswers);
 312          // And that it's for the choice2 activity.
 313          $this->assertEquals($choice2->id, $lastresponse->choiceid);
 314      }
 315  }