Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 * mod_h5pactivity generator tests 19 * 20 * @package mod_h5pactivity 21 * @category test 22 * @copyright 2020 Ferran Recio <ferran@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 use mod_h5pactivity\local\manager; 27 28 /** 29 * Genarator tests class for mod_h5pactivity. 30 * 31 * @package mod_h5pactivity 32 * @category test 33 * @copyright 2020 Ferran Recio <ferran@moodle.com> 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class mod_h5pactivity_generator_testcase extends advanced_testcase { 37 38 /** 39 * Test on H5P activity creation. 40 */ 41 public function test_create_instance() { 42 global $DB, $CFG, $USER; 43 $this->resetAfterTest(); 44 $this->setAdminUser(); 45 46 $course = $this->getDataGenerator()->create_course(); 47 48 // Create one activity. 49 $this->assertFalse($DB->record_exists('h5pactivity', ['course' => $course->id])); 50 $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 51 $records = $DB->get_records('h5pactivity', ['course' => $course->id], 'id'); 52 $this->assertEquals(15, $activity->displayoptions); 53 $this->assertEquals(1, count($records)); 54 $this->assertTrue(array_key_exists($activity->id, $records)); 55 56 // Create a second one with different name and dusplay options. 57 $params = [ 58 'course' => $course->id, 'name' => 'Another h5pactivity', 'displayoptions' => 6, 59 'enabletracking' => 0, 'grademethod' => manager::GRADELASTATTEMPT, 60 ]; 61 $activity = $this->getDataGenerator()->create_module('h5pactivity', $params); 62 $records = $DB->get_records('h5pactivity', ['course' => $course->id], 'id'); 63 $this->assertEquals(6, $activity->displayoptions); 64 $this->assertEquals(0, $activity->enabletracking); 65 $this->assertEquals(manager::GRADELASTATTEMPT, $activity->grademethod); 66 $this->assertEquals(manager::REVIEWCOMPLETION, $activity->reviewmode); 67 $this->assertEquals(2, count($records)); 68 $this->assertEquals('Another h5pactivity', $records[$activity->id]->name); 69 70 // Examples of specifying the package file (do not validate anything, just check for exceptions). 71 // 1. As path to the file in filesystem. 72 $params = [ 73 'course' => $course->id, 74 'packagefilepath' => $CFG->dirroot.'/h5p/tests/fixtures/filltheblanks.h5p' 75 ]; 76 $activity = $this->getDataGenerator()->create_module('h5pactivity', $params); 77 78 // 2. As file draft area id. 79 $fs = get_file_storage(); 80 $params = [ 81 'course' => $course->id, 82 'packagefile' => file_get_unused_draft_itemid() 83 ]; 84 $usercontext = context_user::instance($USER->id); 85 $filerecord = ['component' => 'user', 'filearea' => 'draft', 86 'contextid' => $usercontext->id, 'itemid' => $params['packagefile'], 87 'filename' => 'singlescobasic.zip', 'filepath' => '/']; 88 $filepath = $CFG->dirroot.'/h5p/tests/fixtures/filltheblanks.h5p'; 89 $fs->create_file_from_pathname($filerecord, $filepath); 90 $activity = $this->getDataGenerator()->create_module('h5pactivity', $params); 91 } 92 93 /** 94 * Test that a new H5P activity cannot be generated without a valid file 95 * other user. 96 */ 97 public function test_create_file_exception() { 98 global $CFG; 99 $this->resetAfterTest(); 100 $this->setAdminUser(); 101 102 $course = $this->getDataGenerator()->create_course(); 103 104 // Testing generator exceptions. 105 $params = [ 106 'course' => $course->id, 107 'packagefilepath' => $CFG->dirroot.'/h5p/tests/fixtures/wrong_file_.xxx' 108 ]; 109 $this->expectException(coding_exception::class); 110 $activity = $this->getDataGenerator()->create_module('h5pactivity', $params); 111 } 112 113 /** 114 * Test to create H5P attempts 115 * 116 * @dataProvider create_attempt_data 117 * 118 * @param array $tracks the attempt tracks objects 119 * @param int $attempts the final registered attempts 120 * @param int $results the final registered attempts results 121 * @param bool $exception if an exception is expected 122 * 123 */ 124 public function test_create_attempt(array $tracks, int $attempts, int $results, bool $exception) { 125 global $DB; 126 $this->resetAfterTest(); 127 $this->setAdminUser(); 128 129 $course = $this->getDataGenerator()->create_course(); 130 $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 131 $user = $this->getDataGenerator()->create_and_enrol($course, 'student'); 132 133 $this->assertEquals(0, $DB->count_records('h5pactivity_attempts')); 134 $this->assertEquals(0, $DB->count_records('h5pactivity_attempts_results')); 135 136 if ($exception) { 137 $this->expectException(Exception::class); 138 } 139 140 foreach ($tracks as $track) { 141 $attemptinfo = [ 142 'userid' => $user->id, 143 'h5pactivityid' => $activity->id, 144 'attempt' => $track['attempt'], 145 'interactiontype' => $track['interactiontype'], 146 'rawscore' => $track['rawscore'], 147 'maxscore' => $track['maxscore'], 148 'duration' => $track['duration'], 149 'completion' => $track['completion'], 150 'success' => $track['success'], 151 ]; 152 153 $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity'); 154 $generator->create_attempt($attemptinfo); 155 156 $this->assert_attempt_matches_info($attemptinfo); 157 } 158 159 $this->assertEquals($attempts, $DB->count_records('h5pactivity_attempts')); 160 $this->assertEquals($results, $DB->count_records('h5pactivity_attempts_results')); 161 } 162 163 /** 164 * Data provider for create attempt test. 165 * 166 * @return array 167 */ 168 public function create_attempt_data(): array { 169 return [ 170 'Compound statement' => [ 171 [ 172 [ 173 'interactiontype' => 'compound', 'attempt' => 1, 'rawscore' => 2, 174 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 175 ], 176 ], 1, 1, false, 177 ], 178 'Choice statement' => [ 179 [ 180 [ 181 'interactiontype' => 'choice', 'attempt' => 1, 'rawscore' => 2, 182 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 183 ], 184 ], 1, 1, false, 185 ], 186 'Matching statement' => [ 187 [ 188 [ 189 'interactiontype' => 'matching', 'attempt' => 1, 'rawscore' => 2, 190 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 191 ], 192 ], 1, 1, false, 193 ], 194 'Fill-in statement' => [ 195 [ 196 [ 197 'interactiontype' => 'fill-in', 'attempt' => 1, 'rawscore' => 2, 198 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 199 ], 200 ], 1, 1, false, 201 ], 202 'True-false statement' => [ 203 [ 204 [ 205 'interactiontype' => 'true-false', 'attempt' => 1, 'rawscore' => 2, 206 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 207 ], 208 ], 1, 1, false, 209 ], 210 'Long-fill-in statement' => [ 211 [ 212 [ 213 'interactiontype' => 'long-fill-in', 'attempt' => 1, 'rawscore' => 2, 214 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 215 ], 216 ], 1, 1, false, 217 ], 218 'Sequencing statement' => [ 219 [ 220 [ 221 'interactiontype' => 'sequencing', 'attempt' => 1, 'rawscore' => 2, 222 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 223 ], 224 ], 1, 1, false, 225 ], 226 'Other statement' => [ 227 [ 228 [ 229 'interactiontype' => 'other', 'attempt' => 1, 'rawscore' => 2, 230 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 231 ], 232 ], 1, 1, false, 233 ], 234 'Other statement' => [ 235 [ 236 [ 237 'interactiontype' => 'other', 'attempt' => 1, 'rawscore' => 2, 238 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 239 ], 240 ], 1, 1, false, 241 ], 242 'No graded statement' => [ 243 [ 244 [ 245 'interactiontype' => 'other', 'attempt' => 1, 'rawscore' => 0, 246 'maxscore' => 0, 'duration' => 1, 'completion' => 1, 'success' => 0 247 ], 248 ], 1, 1, false, 249 ], 250 'Invalid statement type' => [ 251 [ 252 [ 253 'interactiontype' => 'no-valid-statement-type', 'attempt' => 1, 'rawscore' => 2, 254 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 255 ], 256 ], 0, 0, true, 257 ], 258 'Adding a second statement to attempt' => [ 259 [ 260 [ 261 'interactiontype' => 'true-false', 'attempt' => 1, 'rawscore' => 2, 262 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 263 ], 264 [ 265 'interactiontype' => 'compound', 'attempt' => 1, 'rawscore' => 3, 266 'maxscore' => 3, 'duration' => 2, 'completion' => 1, 'success' => 0 267 ], 268 ], 1, 2, false, 269 ], 270 'Creating two attempts' => [ 271 [ 272 [ 273 'interactiontype' => 'compound', 'attempt' => 1, 'rawscore' => 2, 274 'maxscore' => 2, 'duration' => 1, 'completion' => 1, 'success' => 0 275 ], 276 [ 277 'interactiontype' => 'compound', 'attempt' => 2, 'rawscore' => 3, 278 'maxscore' => 3, 'duration' => 1, 'completion' => 1, 'success' => 0 279 ], 280 ], 2, 2, false, 281 ], 282 ]; 283 } 284 285 /** 286 * Insert track into attempt, creating the attempt if necessary. 287 * 288 * @param array $attemptinfo the attempt track information 289 */ 290 private function assert_attempt_matches_info($attemptinfo): void { 291 global $DB; 292 293 $attempt = $DB->get_record('h5pactivity_attempts', [ 294 'userid' => $attemptinfo['userid'], 295 'h5pactivityid' => $attemptinfo['h5pactivityid'], 296 'attempt' => $attemptinfo['attempt'], 297 ]); 298 $this->assertEquals($attemptinfo['rawscore'], $attempt->rawscore); 299 $this->assertEquals($attemptinfo['maxscore'], $attempt->maxscore); 300 $this->assertEquals($attemptinfo['duration'], $attempt->duration); 301 $this->assertEquals($attemptinfo['completion'], $attempt->completion); 302 $this->assertEquals($attemptinfo['success'], $attempt->success); 303 304 $track = $DB->get_record('h5pactivity_attempts_results', [ 305 'attemptid' => $attempt->id, 306 'interactiontype' => $attemptinfo['interactiontype'], 307 ]); 308 $this->assertEquals($attemptinfo['rawscore'], $track->rawscore); 309 $this->assertEquals($attemptinfo['maxscore'], $track->maxscore); 310 $this->assertEquals($attemptinfo['duration'], $track->duration); 311 $this->assertEquals($attemptinfo['completion'], $track->completion); 312 $this->assertEquals($attemptinfo['success'], $track->success); 313 } 314 315 /** 316 * Test exceptions when creating an invalid attempt. 317 * 318 * @dataProvider create_attempt_exceptions_data 319 * 320 * @param bool $validmod if the activity id is provided 321 * @param bool $validuser if the user id is provided 322 */ 323 public function test_create_attempt_exceptions(bool $validmod, bool $validuser) { 324 global $DB; 325 $this->resetAfterTest(); 326 $this->setAdminUser(); 327 328 $course = $this->getDataGenerator()->create_course(); 329 $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 330 $user = $this->getDataGenerator()->create_and_enrol($course, 'student'); 331 332 $this->expectException(coding_exception::class); 333 334 $attemptinfo = [ 335 'attempt' => 1, 336 'interactiontype' => 'compound', 337 'rawscore' => 2, 338 'maxscore' => 1, 339 'duration' => 1, 340 'completion' => 1, 341 'success' => 0, 342 ]; 343 344 if ($validmod) { 345 $attemptinfo['h5pactivityid'] = $activity->id; 346 } 347 348 if ($validuser) { 349 $attemptinfo['userid'] = $user->id; 350 } 351 352 $generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity'); 353 $generator->create_attempt($attemptinfo); 354 } 355 356 /** 357 * Data provider for data request creation tests. 358 * 359 * @return array 360 */ 361 public function create_attempt_exceptions_data(): array { 362 return [ 363 'Invalid user' => [true, false], 364 'Invalid activity' => [false, true], 365 'Invalid user and activity' => [false, false], 366 ]; 367 } 368 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body