See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 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 * Unit tests for mod_lti lib 19 * 20 * @package mod_lti 21 * @category external 22 * @copyright 2015 Juan Leyva <juan@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 * @since Moodle 3.0 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Unit tests for mod_lti lib 31 * 32 * @package mod_lti 33 * @category external 34 * @copyright 2015 Juan Leyva <juan@moodle.com> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 * @since Moodle 3.0 37 */ 38 class mod_lti_lib_testcase extends advanced_testcase { 39 40 /** 41 * Prepares things before this test case is initialised 42 * @return void 43 */ 44 public static function setUpBeforeClass() { 45 global $CFG; 46 require_once($CFG->dirroot . '/mod/lti/lib.php'); 47 } 48 49 /** 50 * Test lti_view 51 * @return void 52 */ 53 public function test_lti_view() { 54 global $CFG; 55 56 $CFG->enablecompletion = 1; 57 $this->resetAfterTest(); 58 59 $this->setAdminUser(); 60 // Setup test data. 61 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 62 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id), 63 array('completion' => 2, 'completionview' => 1)); 64 $context = context_module::instance($lti->cmid); 65 $cm = get_coursemodule_from_instance('lti', $lti->id); 66 67 // Trigger and capture the event. 68 $sink = $this->redirectEvents(); 69 70 lti_view($lti, $course, $cm, $context); 71 72 $events = $sink->get_events(); 73 // 2 additional events thanks to completion. 74 $this->assertCount(3, $events); 75 $event = array_shift($events); 76 77 // Checking that the event contains the expected values. 78 $this->assertInstanceOf('\mod_lti\event\course_module_viewed', $event); 79 $this->assertEquals($context, $event->get_context()); 80 $moodleurl = new \moodle_url('/mod/lti/view.php', array('id' => $cm->id)); 81 $this->assertEquals($moodleurl, $event->get_url()); 82 $this->assertEventContextNotUsed($event); 83 $this->assertNotEmpty($event->get_name()); 84 85 // Check completion status. 86 $completion = new completion_info($course); 87 $completiondata = $completion->get_data($cm); 88 $this->assertEquals(1, $completiondata->completionstate); 89 90 } 91 92 /** 93 * Test deleting LTI instance. 94 */ 95 public function test_lti_delete_instance() { 96 $this->resetAfterTest(); 97 98 $this->setAdminUser(); 99 $course = $this->getDataGenerator()->create_course(array()); 100 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id)); 101 $cm = get_coursemodule_from_instance('lti', $lti->id); 102 103 // Must not throw notices. 104 course_delete_module($cm->id); 105 } 106 107 public function test_lti_core_calendar_provide_event_action() { 108 $this->resetAfterTest(); 109 $this->setAdminUser(); 110 111 // Create the activity. 112 $course = $this->getDataGenerator()->create_course(); 113 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id)); 114 115 // Create a calendar event. 116 $event = $this->create_action_event($course->id, $lti->id, 117 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 118 119 // Create an action factory. 120 $factory = new \core_calendar\action_factory(); 121 122 // Decorate action event. 123 $actionevent = mod_lti_core_calendar_provide_event_action($event, $factory); 124 125 // Confirm the event was decorated. 126 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 127 $this->assertEquals(get_string('view'), $actionevent->get_name()); 128 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 129 $this->assertEquals(1, $actionevent->get_item_count()); 130 $this->assertTrue($actionevent->is_actionable()); 131 } 132 133 public function test_lti_core_calendar_provide_event_action_as_non_user() { 134 global $CFG; 135 136 $this->resetAfterTest(); 137 $this->setAdminUser(); 138 139 // Create the activity. 140 $course = $this->getDataGenerator()->create_course(); 141 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id)); 142 143 // Create a calendar event. 144 $event = $this->create_action_event($course->id, $lti->id, 145 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 146 147 // Now, log out. 148 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 149 $this->setUser(); 150 151 // Create an action factory. 152 $factory = new \core_calendar\action_factory(); 153 154 // Decorate action event. 155 $actionevent = mod_lti_core_calendar_provide_event_action($event, $factory); 156 157 // Confirm the event is not shown at all. 158 $this->assertNull($actionevent); 159 } 160 161 public function test_lti_core_calendar_provide_event_action_for_user() { 162 global $CFG; 163 164 $this->resetAfterTest(); 165 $this->setAdminUser(); 166 167 // Create the activity. 168 $course = $this->getDataGenerator()->create_course(); 169 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id)); 170 171 // Enrol a student in the course. 172 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 173 174 // Create a calendar event. 175 $event = $this->create_action_event($course->id, $lti->id, 176 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 177 178 // Now, log out. 179 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 180 $this->setUser(); 181 182 // Create an action factory. 183 $factory = new \core_calendar\action_factory(); 184 185 // Decorate action event for the student. 186 $actionevent = mod_lti_core_calendar_provide_event_action($event, $factory, $student->id); 187 188 // Confirm the event was decorated. 189 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 190 $this->assertEquals(get_string('view'), $actionevent->get_name()); 191 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 192 $this->assertEquals(1, $actionevent->get_item_count()); 193 $this->assertTrue($actionevent->is_actionable()); 194 } 195 196 public function test_lti_core_calendar_provide_event_action_already_completed() { 197 global $CFG; 198 199 $this->resetAfterTest(); 200 $this->setAdminUser(); 201 202 $CFG->enablecompletion = 1; 203 204 // Create the activity. 205 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 206 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id), 207 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 208 209 // Get some additional data. 210 $cm = get_coursemodule_from_instance('lti', $lti->id); 211 212 // Create a calendar event. 213 $event = $this->create_action_event($course->id, $lti->id, 214 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 215 216 // Mark the activity as completed. 217 $completion = new completion_info($course); 218 $completion->set_module_viewed($cm); 219 220 // Create an action factory. 221 $factory = new \core_calendar\action_factory(); 222 223 // Decorate action event. 224 $actionevent = mod_lti_core_calendar_provide_event_action($event, $factory); 225 226 // Ensure result was null. 227 $this->assertNull($actionevent); 228 } 229 230 public function test_lti_core_calendar_provide_event_action_already_completed_as_non_user() { 231 global $CFG; 232 233 $this->resetAfterTest(); 234 $this->setAdminUser(); 235 236 $CFG->enablecompletion = 1; 237 238 // Create the activity. 239 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 240 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id), 241 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 242 243 // Get some additional data. 244 $cm = get_coursemodule_from_instance('lti', $lti->id); 245 246 // Create a calendar event. 247 $event = $this->create_action_event($course->id, $lti->id, 248 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 249 250 // Mark the activity as completed. 251 $completion = new completion_info($course); 252 $completion->set_module_viewed($cm); 253 254 // Now, log out. 255 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 256 $this->setUser(); 257 258 // Create an action factory. 259 $factory = new \core_calendar\action_factory(); 260 261 // Decorate action event. 262 $actionevent = mod_lti_core_calendar_provide_event_action($event, $factory); 263 264 // Ensure result was null. 265 $this->assertNull($actionevent); 266 } 267 268 public function test_lti_core_calendar_provide_event_action_already_completed_for_user() { 269 global $CFG; 270 271 $this->resetAfterTest(); 272 $this->setAdminUser(); 273 274 $CFG->enablecompletion = 1; 275 276 // Create the activity. 277 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 278 $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id), 279 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 280 281 // Enrol 2 students in the course. 282 $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student'); 283 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student'); 284 285 // Get some additional data. 286 $cm = get_coursemodule_from_instance('lti', $lti->id); 287 288 // Create a calendar event. 289 $event = $this->create_action_event($course->id, $lti->id, 290 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 291 292 // Mark the activity as completed for $student1. 293 $completion = new completion_info($course); 294 $completion->set_module_viewed($cm, $student1->id); 295 296 // Now, log in as $student2. 297 $this->setUser($student2); 298 299 // Create an action factory. 300 $factory = new \core_calendar\action_factory(); 301 302 // Decorate action event for $student1. 303 $actionevent = mod_lti_core_calendar_provide_event_action($event, $factory, $student1->id); 304 305 // Ensure result was null. 306 $this->assertNull($actionevent); 307 } 308 309 /** 310 * Creates an action event. 311 * 312 * @param int $courseid The course id. 313 * @param int $instanceid The instance id. 314 * @param string $eventtype The event type. 315 * @return bool|calendar_event 316 */ 317 private function create_action_event($courseid, $instanceid, $eventtype) { 318 $event = new stdClass(); 319 $event->name = 'Calendar event'; 320 $event->modulename = 'lti'; 321 $event->courseid = $courseid; 322 $event->instance = $instanceid; 323 $event->type = CALENDAR_EVENT_TYPE_ACTION; 324 $event->eventtype = $eventtype; 325 $event->timestart = time(); 326 327 return calendar_event::create($event); 328 } 329 330 /** 331 * Test verifying the output of the lti_get_course_content_items and lti_get_all_content_items callbacks. 332 */ 333 public function test_content_item_callbacks() { 334 $this->resetAfterTest(); 335 global $DB, $CFG; 336 require_once($CFG->dirroot . '/mod/lti/locallib.php'); 337 338 $admin = get_admin(); 339 $time = time(); 340 $course = $this->getDataGenerator()->create_course(); 341 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher'); 342 $course2 = $this->getDataGenerator()->create_course(); 343 $teacher2 = $this->getDataGenerator()->create_and_enrol($course2, 'editingteacher'); 344 345 // Create some preconfigured tools. 346 $sitetoolrecord = (object) [ 347 'name' => 'Site level tool which is available in the activity chooser', 348 'baseurl' => 'http://example.com', 349 'createdby' => $admin->id, 350 'course' => SITEID, 351 'ltiversion' => 'LTI-1p0', 352 'timecreated' => $time, 353 'timemodified' => $time, 354 'state' => LTI_TOOL_STATE_CONFIGURED, 355 'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER 356 ]; 357 $sitetoolrecordnonchooser = (object) [ 358 'name' => 'Site level tool which is NOT available in the course activity chooser', 359 'baseurl' => 'http://example2.com', 360 'createdby' => $admin->id, 361 'course' => SITEID, 362 'ltiversion' => 'LTI-1p0', 363 'timecreated' => $time, 364 'timemodified' => $time, 365 'state' => LTI_TOOL_STATE_CONFIGURED, 366 'coursevisible' => LTI_COURSEVISIBLE_PRECONFIGURED 367 ]; 368 $course1toolrecord = (object) [ 369 'name' => 'Course created tool which is available in the activity chooser', 370 'baseurl' => 'http://example3.com', 371 'createdby' => $teacher->id, 372 'course' => $course->id, 373 'ltiversion' => 'LTI-1p0', 374 'timecreated' => $time, 375 'timemodified' => $time, 376 'state' => LTI_TOOL_STATE_CONFIGURED, 377 'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER 378 ]; 379 $course2toolrecord = (object) [ 380 'name' => 'Course created tool which is available in the activity chooser', 381 'baseurl' => 'http://example4.com', 382 'createdby' => $teacher2->id, 383 'course' => $course2->id, 384 'ltiversion' => 'LTI-1p0', 385 'timecreated' => $time, 386 'timemodified' => $time, 387 'state' => LTI_TOOL_STATE_CONFIGURED, 388 'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER 389 ]; 390 $tool1id = $DB->insert_record('lti_types', $sitetoolrecord); 391 $tool2id = $DB->insert_record('lti_types', $sitetoolrecordnonchooser); 392 $tool3id = $DB->insert_record('lti_types', $course1toolrecord); 393 $tool4id = $DB->insert_record('lti_types', $course2toolrecord); 394 $sitetoolrecord->id = $tool1id; 395 $sitetoolrecordnonchooser->id = $tool2id; 396 $course1toolrecord->id = $tool3id; 397 $course2toolrecord->id = $tool4id; 398 399 $defaultmodulecontentitem = new \core_course\local\entity\content_item( 400 '1', 401 'default module content item', 402 new \core_course\local\entity\string_title('Content item title'), 403 new moodle_url(''), 404 'icon', 405 'Description of the module', 406 MOD_ARCHETYPE_OTHER, 407 'mod_lti' 408 ); 409 410 // The lti_get_lti_types_by_course method (used by the callbacks) assumes the global user. 411 $this->setUser($teacher); 412 413 // Teacher in course1 should be able to see the default module item ('external tool'), 414 // the site preconfigured tool and the tool created in course1. 415 $courseitems = lti_get_course_content_items($defaultmodulecontentitem, $teacher, $course); 416 $this->assertCount(3, $courseitems); 417 $ids = []; 418 foreach ($courseitems as $item) { 419 $ids[] = $item->get_id(); 420 } 421 $this->assertContains(1, $ids); 422 $this->assertContains($sitetoolrecord->id + 1, $ids); 423 $this->assertContains($course1toolrecord->id + 1, $ids); 424 $this->assertNotContains($sitetoolrecordnonchooser->id + 1, $ids); 425 426 // The content items for teacher2 in course2 include the default module content item ('external tool'), 427 // the site preconfigured tool and the tool created in course2. 428 $this->setUser($teacher2); 429 $course2items = lti_get_course_content_items($defaultmodulecontentitem, $teacher2, $course2); 430 $this->assertCount(3, $course2items); 431 $ids = []; 432 foreach ($course2items as $item) { 433 $ids[] = $item->get_id(); 434 } 435 $this->assertContains(1, $ids); 436 $this->assertContains($sitetoolrecord->id + 1, $ids); 437 $this->assertContains($course2toolrecord->id + 1, $ids); 438 $this->assertNotContains($sitetoolrecordnonchooser->id + 1, $ids); 439 440 // When fetching all content items, we expect to see all items available in activity choosers (in any course), 441 // plus the default module content item ('external tool'). 442 $this->setAdminUser(); 443 $allitems = mod_lti_get_all_content_items($defaultmodulecontentitem); 444 $this->assertCount(4, $allitems); 445 $ids = []; 446 foreach ($allitems as $item) { 447 $ids[] = $item->get_id(); 448 } 449 $this->assertContains(1, $ids); 450 $this->assertContains($sitetoolrecord->id + 1, $ids); 451 $this->assertContains($course1toolrecord->id + 1, $ids); 452 $this->assertContains($course2toolrecord->id + 1, $ids); 453 $this->assertNotContains($sitetoolrecordnonchooser->id + 1, $ids); 454 } 455 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body