Differences Between: [Versions 310 and 403] [Versions 311 and 403] [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 namespace core_completion; 18 19 use completion_completion; 20 21 /** 22 * Test completion progress API. 23 * 24 * @package core_completion 25 * @category test 26 * @copyright 2017 Mark Nelson <markn@moodle.com> 27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 28 */ 29 class progress_test extends \advanced_testcase { 30 31 /** 32 * Test setup. 33 */ 34 public function setUp(): void { 35 global $CFG; 36 37 $CFG->enablecompletion = true; 38 $this->resetAfterTest(); 39 } 40 41 /** 42 * Tests that the course progress percentage is returned correctly when we have only activity completion. 43 */ 44 public function test_course_progress_percentage_with_just_activities() { 45 global $DB; 46 47 // Add a course that supports completion. 48 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 49 50 // Enrol a user in the course. 51 $user = $this->getDataGenerator()->create_user(); 52 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 53 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 54 55 // Add four activities that use completion. 56 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id), 57 array('completion' => 1)); 58 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id), 59 array('completion' => 1)); 60 $this->getDataGenerator()->create_module('forum', array('course' => $course->id), 61 array('completion' => 1)); 62 $this->getDataGenerator()->create_module('forum', array('course' => $course->id), 63 array('completion' => 1)); 64 65 // Add an activity that does *not* use completion. 66 $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 67 68 // Mark two of them as completed for a user. 69 $cmassign = get_coursemodule_from_id('assign', $assign->cmid); 70 $cmdata = get_coursemodule_from_id('data', $data->cmid); 71 $completion = new \completion_info($course); 72 $completion->update_state($cmassign, COMPLETION_COMPLETE, $user->id); 73 $completion->update_state($cmdata, COMPLETION_COMPLETE, $user->id); 74 75 // Check we have received valid data. 76 // Note - only 4 out of the 5 activities support completion, and the user has completed 2 of those. 77 $this->assertEquals('50', \core_completion\progress::get_course_progress_percentage($course, $user->id)); 78 } 79 80 /** 81 * Tests that the course progress percentage is returned correctly when we have a course and activity completion. 82 */ 83 public function test_course_progress_percentage_with_activities_and_course() { 84 global $DB; 85 86 // Add a course that supports completion. 87 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 88 89 // Enrol a user in the course. 90 $user = $this->getDataGenerator()->create_user(); 91 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 92 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 93 94 // Add four activities that use completion. 95 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id), 96 array('completion' => 1)); 97 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id), 98 array('completion' => 1)); 99 $this->getDataGenerator()->create_module('forum', array('course' => $course->id), 100 array('completion' => 1)); 101 $this->getDataGenerator()->create_module('forum', array('course' => $course->id), 102 array('completion' => 1)); 103 104 // Add an activity that does *not* use completion. 105 $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 106 107 // Mark two of them as completed for a user. 108 $cmassign = get_coursemodule_from_id('assign', $assign->cmid); 109 $cmdata = get_coursemodule_from_id('data', $data->cmid); 110 $completion = new \completion_info($course); 111 $completion->update_state($cmassign, COMPLETION_COMPLETE, $user->id); 112 $completion->update_state($cmdata, COMPLETION_COMPLETE, $user->id); 113 114 // Now, mark the course as completed. 115 $ccompletion = new completion_completion(array('course' => $course->id, 'userid' => $user->id)); 116 $ccompletion->mark_complete(); 117 118 // Check we have received valid data. 119 // The course completion takes priority, so should return 100. 120 $this->assertEquals('100', \core_completion\progress::get_course_progress_percentage($course, $user->id)); 121 } 122 123 /** 124 * Tests that the course progress percentage is returned correctly for various grade to pass settings 125 * 126 * @covers \core_completion\progress::get_course_progress_percentage. 127 */ 128 public function test_course_progress_percentage_completion_state() { 129 global $DB, $CFG; 130 131 require_once("{$CFG->dirroot}/completion/criteria/completion_criteria_activity.php"); 132 133 // Add a course that supports completion. 134 $course = $this->getDataGenerator()->create_course(['enablecompletion' => 1]); 135 136 // Enrol a user in the course. 137 $teacher = $this->getDataGenerator()->create_user(); 138 $user = $this->getDataGenerator()->create_user(); 139 $studentrole = $DB->get_record('role', ['shortname' => 'student']); 140 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 141 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 142 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); 143 144 // Add three activities that use completion. 145 /** @var \mod_assign_generator $assigngenerator */ 146 $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 147 $assign['passgragepassed'] = $assigngenerator->create_instance([ 148 'course' => $course->id, 149 'completion' => COMPLETION_ENABLED, 150 'completionusegrade' => 1, 151 'gradepass' => 50, 152 'completionpassgrade' => 1 153 ]); 154 155 $assign['passgragefailed'] = $assigngenerator->create_instance([ 156 'course' => $course->id, 157 'completion' => COMPLETION_ENABLED, 158 'completionusegrade' => 1, 159 'gradepass' => 50, 160 'completionpassgrade' => 1 161 ]); 162 163 $assign['passgragenotused'] = $assigngenerator->create_instance([ 164 'course' => $course->id, 165 'completion' => COMPLETION_ENABLED, 166 'completionusegrade' => 1, 167 'gradepass' => 50, 168 ]); 169 170 $assign['nograde'] = $assigngenerator->create_instance([ 171 'course' => $course->id, 172 'completion' => COMPLETION_ENABLED, 173 ]); 174 175 $c = new \completion_info($course); 176 177 foreach ($assign as $item) { 178 $cmassing = get_coursemodule_from_id('assign', $item->cmid); 179 180 // Add activity completion criteria. 181 $criteriadata = new \stdClass(); 182 $criteriadata->id = $course->id; 183 $criteriadata->criteria_activity = []; 184 // Some activities. 185 $criteriadata->criteria_activity[$cmassing->id] = 1; 186 $criterion = new \completion_criteria_activity(); 187 $criterion->update_config($criteriadata); 188 } 189 190 $this->setUser($teacher); 191 192 foreach ($assign as $key => $item) { 193 $cm = get_coursemodule_from_instance('assign', $item->id); 194 195 // Mark user completions. 196 $completion = new \stdClass(); 197 $completion->coursemoduleid = $cm->id; 198 $completion->timemodified = time(); 199 $completion->viewed = COMPLETION_NOT_VIEWED; 200 $completion->overrideby = null; 201 202 if ($key == 'passgragepassed') { 203 $completion->id = 0; 204 $completion->completionstate = COMPLETION_COMPLETE_PASS; 205 $completion->userid = $user->id; 206 $c->internal_set_data($cm, $completion, true); 207 } else if ($key == 'passgragefailed') { 208 $completion->id = 0; 209 $completion->completionstate = COMPLETION_COMPLETE_FAIL; 210 $completion->userid = $user->id; 211 $c->internal_set_data($cm, $completion, true); 212 } else if ($key == 'passgragenotused') { 213 $completion->id = 0; 214 $completion->completionstate = COMPLETION_COMPLETE; 215 $completion->userid = $user->id; 216 $c->internal_set_data($cm, $completion, true); 217 } else if ($key == 'nograde') { 218 $completion->id = 0; 219 $completion->completionstate = COMPLETION_COMPLETE; 220 $completion->userid = $user->id; 221 $c->internal_set_data($cm, $completion, true); 222 } 223 } 224 225 // Run course completions cron. 226 \core_completion\api::mark_course_completions_activity_criteria(); 227 228 // Check we have received valid data. 229 // Only assign2 is not completed. 230 $this->assertEquals('75', \core_completion\progress::get_course_progress_percentage($course, $user->id)); 231 } 232 233 /** 234 * Tests that the course progress returns null when the course does not support it. 235 */ 236 public function test_course_progress_course_not_using_completion() { 237 // Create a course that does not use completion. 238 $course = $this->getDataGenerator()->create_course(); 239 240 // Check that the result was null. 241 $this->assertNull(\core_completion\progress::get_course_progress_percentage($course)); 242 } 243 244 /** 245 * Tests that the course progress returns null when there are no activities that support it. 246 */ 247 public function test_course_progress_no_activities_using_completion() { 248 // Create a course that does support completion. 249 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 250 251 // Add an activity that does *not* support completion. 252 $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 253 254 // Check that the result was null. 255 $this->assertNull(\core_completion\progress::get_course_progress_percentage($course)); 256 } 257 258 /** 259 * Tests that the course progress returns null for a not tracked for completion user in a course. 260 */ 261 public function test_course_progress_not_tracked_user() { 262 global $DB; 263 264 // Add a course that supports completion. 265 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 266 267 // Enrol a user in the course. 268 $user = $this->getDataGenerator()->create_user(); 269 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 270 271 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 272 273 // Now, mark the course as completed. 274 $ccompletion = new completion_completion(array('course' => $course->id, 'userid' => $user->id)); 275 $ccompletion->mark_complete(); 276 277 // The course completion should return 100. 278 $this->assertEquals('100', \core_completion\progress::get_course_progress_percentage($course, $user->id)); 279 280 // Now make the user's role to be not tracked for completion. 281 unassign_capability('moodle/course:isincompletionreports', $studentrole->id); 282 283 // Check that the result is null now. 284 $this->assertNull(\core_completion\progress::get_course_progress_percentage($course, $user->id)); 285 } 286 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body