See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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_folder lib 19 * 20 * @package mod_folder 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 namespace mod_folder; 27 28 use context_user; 29 use context_module; 30 31 defined('MOODLE_INTERNAL') || die(); 32 33 34 /** 35 * Unit tests for mod_folder lib 36 * 37 * @package mod_folder 38 * @category external 39 * @copyright 2015 Juan Leyva <juan@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 * @since Moodle 3.0 42 */ 43 class lib_test extends \advanced_testcase { 44 45 /** 46 * Setup. 47 */ 48 public function setUp(): void { 49 $this->resetAfterTest(); 50 $this->setAdminUser(); 51 } 52 53 /** 54 * Prepares things before this test case is initialised 55 * @return void 56 */ 57 public static function setUpBeforeClass(): void { 58 global $CFG; 59 require_once($CFG->dirroot . '/mod/folder/lib.php'); 60 } 61 62 /** 63 * Test folder_view 64 * @return void 65 */ 66 public function test_folder_view() { 67 global $CFG; 68 69 $CFG->enablecompletion = 1; 70 71 // Setup test data. 72 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 73 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id), 74 array('completion' => 2, 'completionview' => 1)); 75 $context = \context_module::instance($folder->cmid); 76 $cm = get_coursemodule_from_instance('folder', $folder->id); 77 78 // Trigger and capture the event. 79 $sink = $this->redirectEvents(); 80 81 folder_view($folder, $course, $cm, $context); 82 83 $events = $sink->get_events(); 84 // 2 additional events thanks to completion. 85 $this->assertCount(3, $events); 86 $event = array_shift($events); 87 88 // Checking that the event contains the expected values. 89 $this->assertInstanceOf('\mod_folder\event\course_module_viewed', $event); 90 $this->assertEquals($context, $event->get_context()); 91 $moodleurl = new \moodle_url('/mod/folder/view.php', array('id' => $cm->id)); 92 $this->assertEquals($moodleurl, $event->get_url()); 93 $this->assertEventContextNotUsed($event); 94 $this->assertNotEmpty($event->get_name()); 95 96 // Check completion status. 97 $completion = new \completion_info($course); 98 $completiondata = $completion->get_data($cm); 99 $this->assertEquals(1, $completiondata->completionstate); 100 } 101 102 public function test_folder_core_calendar_provide_event_action() { 103 // Create the activity. 104 $course = $this->getDataGenerator()->create_course(); 105 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id)); 106 107 // Create a calendar event. 108 $event = $this->create_action_event($course->id, $folder->id, 109 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 110 111 // Create an action factory. 112 $factory = new \core_calendar\action_factory(); 113 114 // Decorate action event. 115 $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory); 116 117 // Confirm the event was decorated. 118 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 119 $this->assertEquals(get_string('view'), $actionevent->get_name()); 120 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 121 $this->assertEquals(1, $actionevent->get_item_count()); 122 $this->assertTrue($actionevent->is_actionable()); 123 } 124 125 public function test_folder_core_calendar_provide_event_action_for_non_user() { 126 global $CFG; 127 128 // Create a course. 129 $course = $this->getDataGenerator()->create_course(); 130 131 // Create the activity. 132 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id)); 133 134 // Create a calendar event. 135 $event = $this->create_action_event($course->id, $folder->id, 136 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 137 138 // Now, log out. 139 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 140 $this->setUser(); 141 142 // Create an action factory. 143 $factory = new \core_calendar\action_factory(); 144 145 // Decorate action event. 146 $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory); 147 148 // Confirm the event is not shown at all. 149 $this->assertNull($actionevent); 150 } 151 152 public function test_folder_core_calendar_provide_event_action_in_hidden_section() { 153 // Create a course. 154 $course = $this->getDataGenerator()->create_course(); 155 156 // Create a student. 157 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 158 159 // Create the activity. 160 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id)); 161 162 // Create a calendar event. 163 $event = $this->create_action_event($course->id, $folder->id, 164 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 165 166 // Set sections 0 as hidden. 167 set_section_visible($course->id, 0, 0); 168 169 // Create an action factory. 170 $factory = new \core_calendar\action_factory(); 171 172 // Decorate action event. 173 $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id); 174 175 // Confirm the event is not shown at all. 176 $this->assertNull($actionevent); 177 } 178 179 public function test_folder_core_calendar_provide_event_action_for_user() { 180 // Create a course. 181 $course = $this->getDataGenerator()->create_course(); 182 183 // Create a student. 184 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 185 186 // Create the activity. 187 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id)); 188 189 // Create a calendar event. 190 $event = $this->create_action_event($course->id, $folder->id, 191 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 192 193 // Now, log out. 194 $this->setUser(); 195 196 // Create an action factory. 197 $factory = new \core_calendar\action_factory(); 198 199 // Decorate action event for the student. 200 $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id); 201 202 // Confirm the event was decorated. 203 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 204 $this->assertEquals(get_string('view'), $actionevent->get_name()); 205 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 206 $this->assertEquals(1, $actionevent->get_item_count()); 207 $this->assertTrue($actionevent->is_actionable()); 208 } 209 210 public function test_folder_core_calendar_provide_event_action_already_completed() { 211 global $CFG; 212 213 $CFG->enablecompletion = 1; 214 215 // Create the activity. 216 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 217 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id), 218 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 219 220 // Get some additional data. 221 $cm = get_coursemodule_from_instance('folder', $folder->id); 222 223 // Create a calendar event. 224 $event = $this->create_action_event($course->id, $folder->id, 225 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 226 227 // Mark the activity as completed. 228 $completion = new \completion_info($course); 229 $completion->set_module_viewed($cm); 230 231 // Create an action factory. 232 $factory = new \core_calendar\action_factory(); 233 234 // Decorate action event. 235 $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory); 236 237 // Ensure result was null. 238 $this->assertNull($actionevent); 239 } 240 241 public function test_folder_core_calendar_provide_event_action_already_completed_for_user() { 242 global $CFG; 243 244 $CFG->enablecompletion = 1; 245 246 // Create a course. 247 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 248 249 // Create a student. 250 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 251 252 // Create the activity. 253 $folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id), 254 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 255 256 // Get some additional data. 257 $cm = get_coursemodule_from_instance('folder', $folder->id); 258 259 // Create a calendar event. 260 $event = $this->create_action_event($course->id, $folder->id, 261 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 262 263 // Mark the activity as completed for the student. 264 $completion = new \completion_info($course); 265 $completion->set_module_viewed($cm, $student->id); 266 267 // Now, log out. 268 $this->setUser(); 269 270 // Create an action factory. 271 $factory = new \core_calendar\action_factory(); 272 273 // Decorate action event for the student. 274 $actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id); 275 276 // Ensure result was null. 277 $this->assertNull($actionevent); 278 } 279 280 /** 281 * Creates an action event. 282 * 283 * @param int $courseid The course id. 284 * @param int $instanceid The instance id. 285 * @param string $eventtype The event type. 286 * @return bool|calendar_event 287 */ 288 private function create_action_event($courseid, $instanceid, $eventtype) { 289 $event = new \stdClass(); 290 $event->name = 'Calendar event'; 291 $event->modulename = 'folder'; 292 $event->courseid = $courseid; 293 $event->instance = $instanceid; 294 $event->type = CALENDAR_EVENT_TYPE_ACTION; 295 $event->eventtype = $eventtype; 296 $event->timestart = time(); 297 298 return \calendar_event::create($event); 299 } 300 301 /** 302 * Test Get recent mod activity method. 303 * @covers ::folder_get_recent_mod_activity 304 * @dataProvider folder_get_recent_mod_activity_provider 305 * 306 * @param int $forcedownload The forcedownload option. 307 * @param bool $hascapability if the user has the mod/folder:view capability 308 * @param int $count The expected recent activities entries. 309 */ 310 public function test_folder_get_recent_mod_activity(int $forcedownload, bool $hascapability, int $count) { 311 global $USER, $DB; 312 313 $this->resetAfterTest(); 314 $this->setAdminUser(); 315 316 $course = $this->getDataGenerator()->create_course(); 317 318 // Add files to draft area. 319 $filesitem = file_get_unused_draft_itemid(); 320 $usercontext = context_user::instance($USER->id); 321 $filerecord = [ 322 'component' => 'user', 323 'filearea' => 'draft', 324 'contextid' => $usercontext->id, 325 'itemid' => $filesitem, 326 'filename' => 'file1.txt', 'filepath' => '/', 327 ]; 328 $fs = get_file_storage(); 329 $fs->create_file_from_string($filerecord, 'First test file contents'); 330 // And a second file. 331 $filerecord['filename'] = 'file2.txt'; 332 $fs->create_file_from_string($filerecord, 'Second test file contents'); 333 334 // Create the activity. 335 $module = $this->getDataGenerator()->create_module( 336 'folder', 337 ['course' => $course->id, 'forcedownload' => $forcedownload, 'files' => $filesitem] 338 ); 339 340 // Get some additional data. 341 $cm = get_coursemodule_from_instance('folder', $module->id); 342 $context = context_module::instance($cm->id); 343 344 // Add user with the specific capability. 345 $user = $this->getDataGenerator()->create_user(); 346 $this->getDataGenerator()->enrol_user($user->id, $course->id, 'editingteacher'); 347 if (!$hascapability) { 348 // The recent activiy uses "folder:view" capability which is allowed by default. 349 $role = $DB->get_record('role', ['shortname' => 'editingteacher'], '*', MUST_EXIST); 350 assign_capability('mod/folder:view', CAP_PROHIBIT, $role->id, $context->id, true); 351 } 352 $this->setUser($user); 353 354 // Get the recent activity. 355 $index = 1; 356 $activities = []; 357 folder_get_recent_mod_activity($activities, $index, time() - HOURSECS, $course->id, $cm->id); 358 359 // Check recent activity. 360 $this->assertCount($count, $activities); 361 foreach ($activities as $index => $activity) { 362 $this->assertEquals('folder', $activity->type); 363 $content = $activity->content; 364 $this->assertEquals("file{$index}.txt", $content->filename); 365 $urlparams = $content->url->params(); 366 if ($forcedownload) { 367 $this->assertEquals(1, $urlparams['forcedownload']); 368 } else { 369 $this->assertArrayNotHasKey('forcedownload', $urlparams); 370 } 371 } 372 } 373 374 /** 375 * Data provider for test_folder_get_recent_mod_activity(). 376 * 377 * @return array 378 */ 379 public function folder_get_recent_mod_activity_provider(): array { 380 return [ 381 'Teacher with force download' => [ 382 'forcedownload' => 1, 383 'hascapability' => true, 384 'count' => 2, 385 ], 386 'Teacher with no force download' => [ 387 'forcedownload' => 0, 388 'hascapability' => true, 389 'count' => 2, 390 ], 391 'Invalid user with force download' => [ 392 'forcedownload' => 1, 393 'hascapability' => false, 394 'count' => 0, 395 ], 396 'Invalid user with no force download' => [ 397 'forcedownload' => 0, 398 'hascapability' => false, 399 'count' => 0, 400 ], 401 ]; 402 } 403 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body