See Release Notes
Long Term Support Release
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 * Base class for unit tests for mod_scorm. 19 * 20 * @package mod_scorm 21 * @category test 22 * @copyright 2018 Sara Arjona <sara@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 use mod_scorm\privacy\provider; 29 use core_privacy\local\request\approved_contextlist; 30 use core_privacy\local\request\approved_userlist; 31 use core_privacy\local\request\writer; 32 use core_privacy\tests\provider_testcase; 33 34 /** 35 * Unit tests for mod\scorm\classes\privacy\provider.php 36 * 37 * @copyright 2018 Sara Arjona <sara@moodle.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class mod_scorm_testcase extends provider_testcase { 41 42 /** @var stdClass User without any AICC/SCORM attempt. */ 43 protected $student0; 44 45 /** @var stdClass User with some AICC/SCORM attempt. */ 46 protected $student1; 47 48 /** @var stdClass User with some AICC/SCORM attempt. */ 49 protected $student2; 50 51 /** @var context context_module of the SCORM activity. */ 52 protected $context; 53 54 /** 55 * Test getting the context for the user ID related to this plugin. 56 */ 57 public function test_get_contexts_for_userid() { 58 $this->resetAfterTest(true); 59 $this->setAdminUser(); 60 $this->scorm_setup_test_scenario_data(); 61 62 // The student0 hasn't any attempt. 63 $contextlist = provider::get_contexts_for_userid($this->student0->id); 64 $this->assertCount(0, (array) $contextlist->get_contextids()); 65 66 // The student1 has data in the SCORM context. 67 $contextlist = provider::get_contexts_for_userid($this->student1->id); 68 $this->assertCount(1, (array) $contextlist->get_contextids()); 69 $this->assertContains($this->context->id, $contextlist->get_contextids()); 70 } 71 72 /** 73 * Test getting the user IDs for the context related to this plugin. 74 */ 75 public function test_get_users_in_context() { 76 $this->resetAfterTest(true); 77 $this->setAdminUser(); 78 $this->scorm_setup_test_scenario_data(); 79 $component = 'mod_scorm'; 80 81 $userlist = new \core_privacy\local\request\userlist($this->context, $component); 82 provider::get_users_in_context($userlist); 83 84 // Students 1 and 2 have attempts in the SCORM context, student 0 does not. 85 $this->assertCount(2, $userlist); 86 87 $expected = [$this->student1->id, $this->student2->id]; 88 $actual = $userlist->get_userids(); 89 sort($expected); 90 sort($actual); 91 $this->assertEquals($expected, $actual); 92 } 93 94 /** 95 * Test that data is exported correctly for this plugin. 96 */ 97 public function test_export_user_data() { 98 $this->resetAfterTest(true); 99 $this->setAdminUser(); 100 $this->scorm_setup_test_scenario_data(); 101 102 // Validate exported data for student0 (without any AICC/SCORM attempt). 103 $this->setUser($this->student0); 104 $writer = writer::with_context($this->context); 105 106 $this->export_context_data_for_user($this->student0->id, $this->context, 'mod_scorm'); 107 $subcontextattempt1 = [ 108 get_string('myattempts', 'scorm'), 109 get_string('attempt', 'scorm'). " 1" 110 ]; 111 $subcontextaicc = [ 112 get_string('myaiccsessions', 'scorm') 113 ]; 114 $data = $writer->get_data($subcontextattempt1); 115 $this->assertEmpty($data); 116 $data = $writer->get_data($subcontextaicc); 117 $this->assertEmpty($data); 118 119 // Validate exported data for student1. 120 writer::reset(); 121 $this->setUser($this->student1); 122 $writer = writer::with_context($this->context); 123 $this->assertFalse($writer->has_any_data()); 124 $this->export_context_data_for_user($this->student1->id, $this->context, 'mod_scorm'); 125 126 $data = $writer->get_data([]); 127 $this->assertEquals('SCORM1', $data->name); 128 129 $data = $writer->get_data($subcontextattempt1); 130 $this->assertCount(1, (array) $data); 131 $this->assertCount(2, (array) reset($data)); 132 $subcontextattempt2 = [ 133 get_string('myattempts', 'scorm'), 134 get_string('attempt', 'scorm'). " 2" 135 ]; 136 $data = $writer->get_data($subcontextattempt2); 137 $this->assertCount(2, (array) reset($data)); 138 // The student1 has only 2 scoes_track attempts. 139 $subcontextattempt3 = [ 140 get_string('myattempts', 'scorm'), 141 get_string('attempt', 'scorm'). " 3" 142 ]; 143 $data = $writer->get_data($subcontextattempt3); 144 $this->assertEmpty($data); 145 // The student1 has only 1 aicc_session. 146 $data = $writer->get_data($subcontextaicc); 147 $this->assertCount(1, (array) $data); 148 } 149 150 /** 151 * Test for provider::delete_data_for_all_users_in_context(). 152 */ 153 public function test_delete_data_for_all_users_in_context() { 154 global $DB; 155 156 $this->resetAfterTest(true); 157 $this->setAdminUser(); 158 $this->scorm_setup_test_scenario_data(); 159 160 // Before deletion, we should have 8 entries in the scorm_scoes_track table. 161 $count = $DB->count_records('scorm_scoes_track'); 162 $this->assertEquals(8, $count); 163 // Before deletion, we should have 4 entries in the scorm_aicc_session table. 164 $count = $DB->count_records('scorm_aicc_session'); 165 $this->assertEquals(4, $count); 166 167 // Delete data based on the context. 168 provider::delete_data_for_all_users_in_context($this->context); 169 170 // After deletion, the scorm_scoes_track entries should have been deleted. 171 $count = $DB->count_records('scorm_scoes_track'); 172 $this->assertEquals(0, $count); 173 // After deletion, the scorm_aicc_session entries should have been deleted. 174 $count = $DB->count_records('scorm_aicc_session'); 175 $this->assertEquals(0, $count); 176 } 177 178 /** 179 * Test for provider::delete_data_for_user(). 180 */ 181 public function test_delete_data_for_user() { 182 global $DB; 183 184 $this->resetAfterTest(true); 185 $this->setAdminUser(); 186 $this->scorm_setup_test_scenario_data(); 187 188 // Before deletion, we should have 8 entries in the scorm_scoes_track table. 189 $count = $DB->count_records('scorm_scoes_track'); 190 $this->assertEquals(8, $count); 191 // Before deletion, we should have 4 entries in the scorm_aicc_session table. 192 $count = $DB->count_records('scorm_aicc_session'); 193 $this->assertEquals(4, $count); 194 195 $approvedcontextlist = new approved_contextlist($this->student1, 'scorm', [$this->context->id]); 196 provider::delete_data_for_user($approvedcontextlist); 197 198 // After deletion, the scorm_scoes_track entries for the first student should have been deleted. 199 $count = $DB->count_records('scorm_scoes_track', ['userid' => $this->student1->id]); 200 $this->assertEquals(0, $count); 201 $count = $DB->count_records('scorm_scoes_track'); 202 $this->assertEquals(4, $count); 203 // After deletion, the scorm_aicc_session entries for the first student should have been deleted. 204 $count = $DB->count_records('scorm_aicc_session', ['userid' => $this->student1->id]); 205 $this->assertEquals(0, $count); 206 $count = $DB->count_records('scorm_aicc_session'); 207 $this->assertEquals(2, $count); 208 209 // Confirm that the SCORM hasn't been removed. 210 $scormcount = $DB->get_records('scorm'); 211 $this->assertCount(1, (array) $scormcount); 212 213 // Delete scoes_track for student0 (nothing has to be removed). 214 $approvedcontextlist = new approved_contextlist($this->student0, 'scorm', [$this->context->id]); 215 provider::delete_data_for_user($approvedcontextlist); 216 $count = $DB->count_records('scorm_scoes_track'); 217 $this->assertEquals(4, $count); 218 $count = $DB->count_records('scorm_aicc_session'); 219 $this->assertEquals(2, $count); 220 } 221 222 /** 223 * Test for provider::delete_data_for_users(). 224 */ 225 public function test_delete_data_for_users() { 226 global $DB; 227 $component = 'mod_scorm'; 228 229 $this->resetAfterTest(true); 230 $this->setAdminUser(); 231 $this->scorm_setup_test_scenario_data(); 232 233 // Before deletion, we should have 8 entries in the scorm_scoes_track table. 234 $count = $DB->count_records('scorm_scoes_track'); 235 $this->assertEquals(8, $count); 236 // Before deletion, we should have 4 entries in the scorm_aicc_session table. 237 $count = $DB->count_records('scorm_aicc_session'); 238 $this->assertEquals(4, $count); 239 240 // Delete only student 1's data, retain student 2's data. 241 $approveduserids = [$this->student1->id]; 242 $approvedlist = new approved_userlist($this->context, $component, $approveduserids); 243 provider::delete_data_for_users($approvedlist); 244 245 // After deletion, the scorm_scoes_track entries for the first student should have been deleted. 246 $count = $DB->count_records('scorm_scoes_track', ['userid' => $this->student1->id]); 247 $this->assertEquals(0, $count); 248 $count = $DB->count_records('scorm_scoes_track'); 249 $this->assertEquals(4, $count); 250 251 // After deletion, the scorm_aicc_session entries for the first student should have been deleted. 252 $count = $DB->count_records('scorm_aicc_session', ['userid' => $this->student1->id]); 253 $this->assertEquals(0, $count); 254 $count = $DB->count_records('scorm_aicc_session'); 255 $this->assertEquals(2, $count); 256 257 // Confirm that the SCORM hasn't been removed. 258 $scormcount = $DB->get_records('scorm'); 259 $this->assertCount(1, (array) $scormcount); 260 261 // Delete scoes_track for student0 (nothing has to be removed). 262 $approveduserids = [$this->student0->id]; 263 $approvedlist = new approved_userlist($this->context, $component, $approveduserids); 264 provider::delete_data_for_users($approvedlist); 265 266 $count = $DB->count_records('scorm_scoes_track'); 267 $this->assertEquals(4, $count); 268 $count = $DB->count_records('scorm_aicc_session'); 269 $this->assertEquals(2, $count); 270 } 271 272 /** 273 * Helper function to setup 3 users and 2 SCORM attempts for student1 and student2. 274 * $this->student0 is always created without any attempt. 275 */ 276 protected function scorm_setup_test_scenario_data() { 277 global $DB; 278 279 set_config('allowaicchacp', 1, 'scorm'); 280 281 // Setup test data. 282 $course = $this->getDataGenerator()->create_course(); 283 $params = array('course' => $course->id, 'name' => 'SCORM1'); 284 $scorm = $this->getDataGenerator()->create_module('scorm', $params); 285 $this->context = \context_module::instance($scorm->cmid); 286 287 // Users enrolments. 288 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 289 290 // Create student0 withot any SCORM attempt. 291 $this->student0 = self::getDataGenerator()->create_user(); 292 $this->getDataGenerator()->enrol_user($this->student0->id, $course->id, $studentrole->id, 'manual'); 293 294 // Create student1 with 2 SCORM attempts and 1 AICC session. 295 $this->student1 = self::getDataGenerator()->create_user(); 296 $this->getDataGenerator()->enrol_user($this->student1->id, $course->id, $studentrole->id, 'manual'); 297 static::scorm_insert_attempt($scorm, $this->student1->id, 1); 298 static::scorm_insert_attempt($scorm, $this->student1->id, 2); 299 300 // Create student2 with 2 SCORM attempts and 1 AICC session. 301 $this->student2 = self::getDataGenerator()->create_user(); 302 $this->getDataGenerator()->enrol_user($this->student2->id, $course->id, $studentrole->id, 'manual'); 303 static::scorm_insert_attempt($scorm, $this->student2->id, 1); 304 static::scorm_insert_attempt($scorm, $this->student2->id, 2); 305 } 306 307 /** 308 * Create a SCORM attempt. 309 * 310 * @param object $scorm SCORM activity. 311 * @param int $userid Userid who is doing the attempt. 312 * @param int $attempt Number of attempt. 313 */ 314 protected function scorm_insert_attempt($scorm, $userid, $attempt) { 315 global $DB; 316 317 $newattempt = 'on'; 318 $mode = 'normal'; 319 scorm_check_mode($scorm, $newattempt, $attempt, $userid, $mode); 320 $scoes = scorm_get_scoes($scorm->id); 321 $sco = array_pop($scoes); 322 scorm_insert_track($userid, $scorm->id, $sco->id, $attempt, 'cmi.core.lesson_status', 'completed'); 323 scorm_insert_track($userid, $scorm->id, $sco->id, $attempt, 'cmi.score.min', '0'); 324 $now = time(); 325 $hacpsession = [ 326 'scormid' => $scorm->id, 327 'attempt' => $attempt, 328 'hacpsession' => random_string(20), 329 'userid' => $userid, 330 'timecreated' => $now, 331 'timemodified' => $now 332 ]; 333 $DB->insert_record('scorm_aicc_session', $hacpsession); 334 } 335 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body