Differences Between: [Versions 310 and 311] [Versions 39 and 311]
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_survey lib 19 * 20 * @package mod_survey 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_survey; 27 28 defined('MOODLE_INTERNAL') || die(); 29 30 31 /** 32 * Unit tests for mod_survey lib 33 * 34 * @package mod_survey 35 * @category external 36 * @copyright 2015 Juan Leyva <juan@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 * @since Moodle 3.0 39 */ 40 class lib_test extends \advanced_testcase { 41 42 /** 43 * Prepares things before this test case is initialised 44 * @return void 45 */ 46 public static function setUpBeforeClass(): void { 47 global $CFG; 48 require_once($CFG->dirroot . '/mod/survey/lib.php'); 49 } 50 51 /** 52 * Test survey_view 53 * @return void 54 */ 55 public function test_survey_view() { 56 global $CFG; 57 58 $CFG->enablecompletion = 1; 59 $this->resetAfterTest(); 60 61 $this->setAdminUser(); 62 // Setup test data. 63 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 64 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id), 65 array('completion' => 2, 'completionview' => 1)); 66 $context = \context_module::instance($survey->cmid); 67 $cm = get_coursemodule_from_instance('survey', $survey->id); 68 69 // Trigger and capture the event. 70 $sink = $this->redirectEvents(); 71 72 survey_view($survey, $course, $cm, $context, 'form'); 73 74 $events = $sink->get_events(); 75 // 2 additional events thanks to completion. 76 $this->assertCount(3, $events); 77 $event = array_shift($events); 78 79 // Checking that the event contains the expected values. 80 $this->assertInstanceOf('\mod_survey\event\course_module_viewed', $event); 81 $this->assertEquals($context, $event->get_context()); 82 $moodleurl = new \moodle_url('/mod/survey/view.php', array('id' => $cm->id)); 83 $this->assertEquals($moodleurl, $event->get_url()); 84 $this->assertEquals('form', $event->other['viewed']); 85 $this->assertEventContextNotUsed($event); 86 $this->assertNotEmpty($event->get_name()); 87 // Check completion status. 88 $completion = new \completion_info($course); 89 $completiondata = $completion->get_data($cm); 90 $this->assertEquals(1, $completiondata->completionstate); 91 92 } 93 94 /** 95 * Test survey_order_questions 96 */ 97 public function test_survey_order_questions() { 98 global $DB; 99 100 $this->resetAfterTest(); 101 $course = $this->getDataGenerator()->create_course(); 102 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id)); 103 104 $orderedquestionids = explode(',', $survey->questions); 105 $surveyquestions = $DB->get_records_list("survey_questions", "id", $orderedquestionids); 106 107 $questionsordered = survey_order_questions($surveyquestions, $orderedquestionids); 108 109 // Check one by one the correct order. 110 for ($i = 0; $i < count($orderedquestionids); $i++) { 111 $this->assertEquals($orderedquestionids[$i], $questionsordered[$i]->id); 112 } 113 } 114 115 /** 116 * Test survey_save_answers 117 */ 118 public function test_survey_save_answers() { 119 global $DB; 120 121 $this->resetAfterTest(); 122 $this->setAdminUser(); 123 124 // Setup test data. 125 $course = $this->getDataGenerator()->create_course(); 126 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id)); 127 $context = \context_module::instance($survey->cmid); 128 129 // Build our questions and responses array. 130 $realquestions = array(); 131 $questions = survey_get_questions($survey); 132 $i = 5; 133 foreach ($questions as $q) { 134 if ($q->type > 0) { 135 if ($q->multi) { 136 $subquestions = survey_get_subquestions($q); 137 foreach ($subquestions as $sq) { 138 $key = 'q' . $sq->id; 139 $realquestions[$key] = $i % 5 + 1; 140 $i++; 141 } 142 } else { 143 $key = 'q' . $q->id; 144 $realquestions[$key] = $i % 5 + 1; 145 $i++; 146 } 147 } 148 } 149 150 $sink = $this->redirectEvents(); 151 survey_save_answers($survey, $realquestions, $course, $context); 152 153 // Check the stored answers, they must match. 154 $dbanswers = $DB->get_records_menu('survey_answers', array('survey' => $survey->id), '', 'question, answer1'); 155 foreach ($realquestions as $key => $value) { 156 $id = str_replace('q', '', $key); 157 $this->assertEquals($value, $dbanswers[$id]); 158 } 159 160 // Check events. 161 $events = $sink->get_events(); 162 $this->assertCount(1, $events); 163 $event = array_shift($events); 164 165 // Checking that the event contains the expected values. 166 $this->assertInstanceOf('\mod_survey\event\response_submitted', $event); 167 $this->assertEquals($context, $event->get_context()); 168 $this->assertEquals($survey->id, $event->other['surveyid']); 169 } 170 171 public function test_survey_core_calendar_provide_event_action() { 172 $this->resetAfterTest(); 173 $this->setAdminUser(); 174 175 // Create the activity. 176 $course = $this->getDataGenerator()->create_course(); 177 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id)); 178 179 // Create a calendar event. 180 $event = $this->create_action_event($course->id, $survey->id, 181 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 182 183 // Create an action factory. 184 $factory = new \core_calendar\action_factory(); 185 186 // Decorate action event. 187 $actionevent = mod_survey_core_calendar_provide_event_action($event, $factory); 188 189 // Confirm the event was decorated. 190 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 191 $this->assertEquals(get_string('view'), $actionevent->get_name()); 192 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 193 $this->assertEquals(1, $actionevent->get_item_count()); 194 $this->assertTrue($actionevent->is_actionable()); 195 } 196 197 public function test_survey_core_calendar_provide_event_action_for_user() { 198 global $CFG; 199 200 $this->resetAfterTest(); 201 $this->setAdminUser(); 202 203 // Create the activity. 204 $course = $this->getDataGenerator()->create_course(); 205 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id)); 206 207 // Create a student and enrol into the course. 208 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 209 210 // Create a calendar event. 211 $event = $this->create_action_event($course->id, $survey->id, 212 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 213 214 // Now log out. 215 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 216 $this->setUser(); 217 218 // Create an action factory. 219 $factory = new \core_calendar\action_factory(); 220 221 // Decorate action event for the student. 222 $actionevent = mod_survey_core_calendar_provide_event_action($event, $factory, $student->id); 223 224 // Confirm the event was decorated. 225 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 226 $this->assertEquals(get_string('view'), $actionevent->get_name()); 227 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 228 $this->assertEquals(1, $actionevent->get_item_count()); 229 $this->assertTrue($actionevent->is_actionable()); 230 } 231 232 public function test_survey_core_calendar_provide_event_action_as_non_user() { 233 global $CFG; 234 235 $this->resetAfterTest(); 236 $this->setAdminUser(); 237 238 // Create the activity. 239 $course = $this->getDataGenerator()->create_course(); 240 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id)); 241 242 // Create a calendar event. 243 $event = $this->create_action_event($course->id, $survey->id, 244 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 245 246 // Log out the user and set force login to true. 247 \core\session\manager::init_empty_session(); 248 $CFG->forcelogin = true; 249 250 // Create an action factory. 251 $factory = new \core_calendar\action_factory(); 252 253 // Decorate action event. 254 $actionevent = mod_survey_core_calendar_provide_event_action($event, $factory); 255 256 // Ensure result was null. 257 $this->assertNull($actionevent); 258 } 259 260 public function test_survey_core_calendar_provide_event_action_already_completed() { 261 global $CFG; 262 263 $this->resetAfterTest(); 264 $this->setAdminUser(); 265 266 $CFG->enablecompletion = 1; 267 268 // Create the activity. 269 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 270 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id), 271 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 272 273 // Get some additional data. 274 $cm = get_coursemodule_from_instance('survey', $survey->id); 275 276 // Create a calendar event. 277 $event = $this->create_action_event($course->id, $survey->id, 278 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 279 280 // Mark the activity as completed. 281 $completion = new \completion_info($course); 282 $completion->set_module_viewed($cm); 283 284 // Create an action factory. 285 $factory = new \core_calendar\action_factory(); 286 287 // Decorate action event. 288 $actionevent = mod_survey_core_calendar_provide_event_action($event, $factory); 289 290 // Ensure result was null. 291 $this->assertNull($actionevent); 292 } 293 294 public function test_survey_core_calendar_provide_event_action_already_completed_for_user() { 295 global $CFG; 296 297 $this->resetAfterTest(); 298 $this->setAdminUser(); 299 300 $CFG->enablecompletion = 1; 301 302 // Create the activity. 303 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 304 $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id), 305 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 306 307 // Create 2 students and enrol them into the course. 308 $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student'); 309 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student'); 310 311 // Get some additional data. 312 $cm = get_coursemodule_from_instance('survey', $survey->id); 313 314 // Create a calendar event. 315 $event = $this->create_action_event($course->id, $survey->id, 316 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 317 318 // Mark the activity as completed for the $student1. 319 $completion = new \completion_info($course); 320 $completion->set_module_viewed($cm, $student1->id); 321 322 // Now log in as $student2. 323 $this->setUser($student2); 324 325 // Create an action factory. 326 $factory = new \core_calendar\action_factory(); 327 328 // Decorate action event for $student1. 329 $actionevent = mod_survey_core_calendar_provide_event_action($event, $factory, $student1->id); 330 331 // Ensure result was null. 332 $this->assertNull($actionevent); 333 } 334 335 /** 336 * Creates an action event. 337 * 338 * @param int $courseid The course id. 339 * @param int $instanceid The instance id. 340 * @param string $eventtype The event type. 341 * @return bool|calendar_event 342 */ 343 private function create_action_event($courseid, $instanceid, $eventtype) { 344 $event = new \stdClass(); 345 $event->name = 'Calendar event'; 346 $event->modulename = 'survey'; 347 $event->courseid = $courseid; 348 $event->instance = $instanceid; 349 $event->type = CALENDAR_EVENT_TYPE_ACTION; 350 $event->eventtype = $eventtype; 351 $event->timestart = time(); 352 353 return \calendar_event::create($event); 354 } 355 356 /** 357 * Test the callback responsible for returning the completion rule descriptions. 358 * This function should work given either an instance of the module (cm_info), such as when checking the active rules, 359 * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. 360 */ 361 public function test_mod_survey_completion_get_active_rule_descriptions() { 362 $this->resetAfterTest(); 363 $this->setAdminUser(); 364 365 // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. 366 $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); 367 $survey1 = $this->getDataGenerator()->create_module('survey', [ 368 'course' => $course->id, 369 'completion' => 2, 370 'completionsubmit' => 1, 371 ]); 372 $survey2 = $this->getDataGenerator()->create_module('survey', [ 373 'course' => $course->id, 374 'completion' => 2, 375 'completionsubmit' => 0, 376 ]); 377 $cm1 = \cm_info::create(get_coursemodule_from_instance('survey', $survey1->id)); 378 $cm2 = \cm_info::create(get_coursemodule_from_instance('survey', $survey2->id)); 379 380 // Data for the stdClass input type. 381 // This type of input would occur when checking the default completion rules for an activity type, where we don't have 382 // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. 383 $moddefaults = new \stdClass(); 384 $moddefaults->customdata = ['customcompletionrules' => ['completionsubmit' => 1]]; 385 $moddefaults->completion = 2; 386 387 $activeruledescriptions = [get_string('completionsubmit', 'survey')]; 388 $this->assertEquals(mod_survey_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); 389 $this->assertEquals(mod_survey_get_completion_active_rule_descriptions($cm2), []); 390 $this->assertEquals(mod_survey_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); 391 $this->assertEquals(mod_survey_get_completion_active_rule_descriptions(new \stdClass()), []); 392 } 393 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body