Differences Between: [Versions 310 and 311] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [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 namespace gradereport_user; 18 19 use externallib_advanced_testcase; 20 use gradereport_user_external; 21 22 defined('MOODLE_INTERNAL') || die(); 23 24 global $CFG; 25 26 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 27 require_once($CFG->dirroot . '/grade/report/user/externallib.php'); 28 29 /** 30 * User grade report functions unit tests 31 * 32 * @package gradereport_user 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 */ 37 class externallib_test extends externallib_advanced_testcase { 38 39 /** 40 * Loads some data to be used by the different tests 41 * @param int $s1grade Student 1 grade 42 * @param int $s2grade Student 2 grade 43 * @return array Course and users instances 44 */ 45 private function load_data($s1grade, $s2grade) { 46 global $DB; 47 48 $course = $this->getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1)); 49 50 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 51 $student1 = $this->getDataGenerator()->create_user(array('idnumber' => 'testidnumber')); 52 $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); 53 54 $student2 = $this->getDataGenerator()->create_user(); 55 $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); 56 57 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 58 $teacher = $this->getDataGenerator()->create_user(); 59 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); 60 61 $context = \context_course::instance($course->id); 62 assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $teacherrole->id, $context); 63 accesslib_clear_all_caches_for_unit_testing(); 64 65 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 66 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 67 groups_add_member($group1->id, $student1->id); 68 groups_add_member($group1->id, $teacher->id); 69 groups_add_member($group2->id, $student2->id); 70 71 $assignment = $this->getDataGenerator()->create_module('assign', array('name' => "Test assign", 'course' => $course->id)); 72 $modcontext = get_coursemodule_from_instance('assign', $assignment->id, $course->id); 73 $assignment->cmidnumber = $modcontext->id; 74 75 $student1grade = array('userid' => $student1->id, 'rawgrade' => $s1grade, 'idnumber' => 'testidnumber1'); 76 $student2grade = array('userid' => $student2->id, 'rawgrade' => $s2grade, 'idnumber' => 'testidnumber2'); 77 $studentgrades = array($student1->id => $student1grade, $student2->id => $student2grade); 78 assign_grade_item_update($assignment, $studentgrades); 79 80 return array($course, $teacher, $student1, $student2, $assignment); 81 } 82 83 /** 84 * Test get_grades_table function case teacher 85 */ 86 public function test_get_grades_table_teacher() { 87 88 $this->resetAfterTest(true); 89 90 $s1grade = 80; 91 $s2grade = 60; 92 93 list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); 94 95 // A teacher must see all student grades (in their group only). 96 $this->setUser($teacher); 97 98 $studentgrades = gradereport_user_external::get_grades_table($course->id); 99 $studentgrades = \external_api::clean_returnvalue(gradereport_user_external::get_grades_table_returns(), $studentgrades); 100 101 // No warnings returned. 102 $this->assertCount(0, $studentgrades['warnings']); 103 104 // Check that only grades for the student in the teacher group are returned. 105 $this->assertCount(1, $studentgrades['tables']); 106 107 // Read returned grades. 108 $studentreturnedgrades = array(); 109 $studentreturnedgrades[$studentgrades['tables'][0]['userid']] = 110 (int) $studentgrades['tables'][0]['tabledata'][1]['grade']['content']; 111 112 $this->assertEquals($s1grade, $studentreturnedgrades[$student1->id]); 113 } 114 115 /** 116 * Test get_grades_table function case student 117 */ 118 public function test_get_grades_table_student() { 119 global $CFG, $DB; 120 121 $this->resetAfterTest(true); 122 123 $s1grade = 80; 124 $s2grade = 60; 125 126 list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); 127 128 // A user can see his own grades. 129 $this->setUser($student1); 130 $studentgrade = gradereport_user_external::get_grades_table($course->id, $student1->id); 131 $studentgrade = \external_api::clean_returnvalue(gradereport_user_external::get_grades_table_returns(), $studentgrade); 132 133 // No warnings returned. 134 $this->assertTrue(count($studentgrade['warnings']) == 0); 135 136 $this->assertTrue(count($studentgrade['tables']) == 1); 137 $student1returnedgrade = (int) $studentgrade['tables'][0]['tabledata'][1]['grade']['content']; 138 $this->assertEquals($s1grade, $student1returnedgrade); 139 140 } 141 142 /** 143 * Test get_grades_table function case incorrect permissions 144 */ 145 public function test_get_grades_table_permissions() { 146 global $CFG, $DB; 147 148 $this->resetAfterTest(true); 149 150 $s1grade = 80; 151 $s2grade = 60; 152 153 list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); 154 155 $this->setUser($student2); 156 157 try { 158 $studentgrade = gradereport_user_external::get_grades_table($course->id, $student1->id); 159 $this->fail('Exception expected due to not perissions to view other user grades.'); 160 } catch (\moodle_exception $e) { 161 $this->assertEquals('notingroup', $e->errorcode); 162 } 163 } 164 165 /** 166 * Test view_grade_report function 167 */ 168 public function test_view_grade_report() { 169 global $USER; 170 171 $this->resetAfterTest(true); 172 173 $s1grade = 80; 174 $s2grade = 60; 175 list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); 176 177 // Redirect events to the sink, so we can recover them later. 178 $sink = $this->redirectEvents(); 179 180 $this->setUser($student1); 181 $result = gradereport_user_external::view_grade_report($course->id); 182 $result = \external_api::clean_returnvalue(gradereport_user_external::view_grade_report_returns(), $result); 183 $events = $sink->get_events(); 184 $this->assertCount(1, $events); 185 $event = reset($events); 186 187 // Check the event details are correct. 188 $this->assertInstanceOf('\gradereport_user\event\grade_report_viewed', $event); 189 $this->assertEquals(\context_course::instance($course->id), $event->get_context()); 190 $this->assertEquals($USER->id, $event->get_data()['relateduserid']); 191 192 $this->setUser($teacher); 193 $result = gradereport_user_external::view_grade_report($course->id, $student1->id); 194 $result = \external_api::clean_returnvalue(gradereport_user_external::view_grade_report_returns(), $result); 195 $events = $sink->get_events(); 196 $event = reset($events); 197 $sink->close(); 198 199 // Check the event details are correct. 200 $this->assertInstanceOf('\gradereport_user\event\grade_report_viewed', $event); 201 $this->assertEquals(\context_course::instance($course->id), $event->get_context()); 202 $this->assertEquals($student1->id, $event->get_data()['relateduserid']); 203 204 $this->setUser($student2); 205 try { 206 $studentgrade = gradereport_user_external::view_grade_report($course->id, $student1->id); 207 $this->fail('Exception expected due to not permissions to view other user grades.'); 208 } catch (\moodle_exception $e) { 209 $this->assertEquals('nopermissiontoviewgrades', $e->errorcode); 210 } 211 } 212 213 /** 214 * Test get_grades_items function case teacher 215 */ 216 public function test_get_grade_items_teacher() { 217 218 $this->resetAfterTest(true); 219 220 $s1grade = 80; 221 $s2grade = 60; 222 223 list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); 224 225 // A teacher must see all student grades (in their group only). 226 $this->setUser($teacher); 227 228 grade_set_setting($course->id, 'report_user_showrank', 1); 229 grade_set_setting($course->id, 'report_user_showpercentage', 1); 230 grade_set_setting($course->id, 'report_user_showhiddenitems', 1); 231 grade_set_setting($course->id, 'report_user_showgrade', 1); 232 grade_set_setting($course->id, 'report_user_showfeedback', 1); 233 grade_set_setting($course->id, 'report_user_showweight', 1); 234 grade_set_setting($course->id, 'report_user_showcontributiontocoursetotal', 1); 235 grade_set_setting($course->id, 'report_user_showlettergrade', 1); 236 grade_set_setting($course->id, 'report_user_showaverage', 1); 237 238 $studentgrades = gradereport_user_external::get_grade_items($course->id); 239 $studentgrades = \external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); 240 // No warnings returned. 241 $this->assertCount(0, $studentgrades['warnings']); 242 243 // Check that only grades for the student in the teacher group are returned. 244 $this->assertCount(1, $studentgrades['usergrades']); 245 $this->assertCount(2, $studentgrades['usergrades'][0]['gradeitems']); 246 247 $this->assertEquals($course->id, $studentgrades['usergrades'][0]['courseid']); 248 $this->assertEquals($student1->id, $studentgrades['usergrades'][0]['userid']); 249 // Module grades. 250 $this->assertEquals($assignment->name, $studentgrades['usergrades'][0]['gradeitems'][0]['itemname']); 251 $this->assertEquals('mod', $studentgrades['usergrades'][0]['gradeitems'][0]['itemtype']); 252 $this->assertEquals('assign', $studentgrades['usergrades'][0]['gradeitems'][0]['itemmodule']); 253 $this->assertEquals($assignment->id, $studentgrades['usergrades'][0]['gradeitems'][0]['iteminstance']); 254 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['locked']); 255 $this->assertEquals($assignment->cmidnumber, $studentgrades['usergrades'][0]['gradeitems'][0]['cmid']); 256 $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['itemnumber']); 257 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['outcomeid']); 258 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['scaleid']); 259 $this->assertEquals(80, $studentgrades['usergrades'][0]['gradeitems'][0]['graderaw']); 260 $this->assertEquals('80.00', $studentgrades['usergrades'][0]['gradeitems'][0]['gradeformatted']); 261 $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['grademin']); 262 $this->assertEquals(100, $studentgrades['usergrades'][0]['gradeitems'][0]['grademax']); 263 $this->assertEquals('0–100', $studentgrades['usergrades'][0]['gradeitems'][0]['rangeformatted']); 264 $this->assertEquals('80.00 %', $studentgrades['usergrades'][0]['gradeitems'][0]['percentageformatted']); 265 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['feedback']); 266 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradehiddenbydate']); 267 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeneedsupdate']); 268 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeishidden']); 269 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeislocked']); 270 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeisoverridden']); 271 $this->assertEquals('B-', $studentgrades['usergrades'][0]['gradeitems'][0]['lettergradeformatted']); 272 $this->assertEquals(1, $studentgrades['usergrades'][0]['gradeitems'][0]['rank']); 273 $this->assertEquals(2, $studentgrades['usergrades'][0]['gradeitems'][0]['numusers']); 274 $this->assertEquals(70, $studentgrades['usergrades'][0]['gradeitems'][0]['averageformatted']); 275 276 // Course grades. 277 $this->assertEquals('course', $studentgrades['usergrades'][0]['gradeitems'][1]['itemtype']); 278 $this->assertEquals(80, $studentgrades['usergrades'][0]['gradeitems'][1]['graderaw']); 279 $this->assertEquals('80.00', $studentgrades['usergrades'][0]['gradeitems'][1]['gradeformatted']); 280 $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][1]['grademin']); 281 $this->assertEquals(100, $studentgrades['usergrades'][0]['gradeitems'][1]['grademax']); 282 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['locked']); 283 $this->assertEquals('0–100', $studentgrades['usergrades'][0]['gradeitems'][1]['rangeformatted']); 284 $this->assertEquals('80.00 %', $studentgrades['usergrades'][0]['gradeitems'][1]['percentageformatted']); 285 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][1]['feedback']); 286 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradehiddenbydate']); 287 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradeneedsupdate']); 288 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradeishidden']); 289 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradeislocked']); 290 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradeisoverridden']); 291 $this->assertEquals('B-', $studentgrades['usergrades'][0]['gradeitems'][1]['lettergradeformatted']); 292 $this->assertEquals(1, $studentgrades['usergrades'][0]['gradeitems'][1]['rank']); 293 $this->assertEquals(2, $studentgrades['usergrades'][0]['gradeitems'][1]['numusers']); 294 $this->assertEquals(70, $studentgrades['usergrades'][0]['gradeitems'][1]['averageformatted']); 295 296 // Now, override and lock a grade. 297 $gradegrade = \grade_grade::fetch(['itemid' => $studentgrades['usergrades'][0]['gradeitems'][0]['id'], 298 'userid' => $studentgrades['usergrades'][0]['userid']]); 299 $gradegrade->set_overridden(true); 300 $gradegrade->set_locked(1); 301 302 $studentgrades = gradereport_user_external::get_grade_items($course->id); 303 $studentgrades = \external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); 304 // No warnings returned. 305 $this->assertCount(0, $studentgrades['warnings']); 306 307 // Module grades. 308 $this->assertTrue($studentgrades['usergrades'][0]['gradeitems'][0]['gradeislocked']); 309 $this->assertTrue($studentgrades['usergrades'][0]['gradeitems'][0]['gradeisoverridden']); 310 } 311 312 /** 313 * Test get_grades_items function case student 314 */ 315 public function test_get_grade_items_student() { 316 317 $this->resetAfterTest(true); 318 319 $s1grade = 80; 320 $s2grade = 60; 321 322 list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); 323 324 grade_set_setting($course->id, 'report_user_showrank', 1); 325 grade_set_setting($course->id, 'report_user_showpercentage', 1); 326 grade_set_setting($course->id, 'report_user_showgrade', 1); 327 grade_set_setting($course->id, 'report_user_showfeedback', 1); 328 grade_set_setting($course->id, 'report_user_showweight', 1); 329 grade_set_setting($course->id, 'report_user_showcontributiontocoursetotal', 1); 330 grade_set_setting($course->id, 'report_user_showlettergrade', 1); 331 grade_set_setting($course->id, 'report_user_showaverage', 1); 332 333 $this->setUser($student1); 334 335 $studentgrades = gradereport_user_external::get_grade_items($course->id, $student1->id); 336 $studentgrades = \external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); 337 // No warnings returned. 338 $this->assertCount(0, $studentgrades['warnings']); 339 340 // Check that only grades for the student in the teacher group are returned. 341 $this->assertCount(1, $studentgrades['usergrades']); 342 $this->assertCount(2, $studentgrades['usergrades'][0]['gradeitems']); 343 344 $this->assertEquals($course->id, $studentgrades['usergrades'][0]['courseid']); 345 $this->assertEquals($student1->id, $studentgrades['usergrades'][0]['userid']); 346 $this->assertEquals($student1->idnumber, $studentgrades['usergrades'][0]['useridnumber']); 347 $this->assertEquals($assignment->name, $studentgrades['usergrades'][0]['gradeitems'][0]['itemname']); 348 $this->assertEquals('mod', $studentgrades['usergrades'][0]['gradeitems'][0]['itemtype']); 349 $this->assertEquals('assign', $studentgrades['usergrades'][0]['gradeitems'][0]['itemmodule']); 350 $this->assertEquals($assignment->id, $studentgrades['usergrades'][0]['gradeitems'][0]['iteminstance']); 351 $this->assertNull($studentgrades['usergrades'][0]['gradeitems'][0]['locked']); 352 $this->assertEquals($assignment->cmidnumber, $studentgrades['usergrades'][0]['gradeitems'][0]['cmid']); 353 $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['itemnumber']); 354 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['outcomeid']); 355 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['scaleid']); 356 $this->assertEquals(80, $studentgrades['usergrades'][0]['gradeitems'][0]['graderaw']); 357 $this->assertEquals('80.00', $studentgrades['usergrades'][0]['gradeitems'][0]['gradeformatted']); 358 $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['grademin']); 359 $this->assertEquals(100, $studentgrades['usergrades'][0]['gradeitems'][0]['grademax']); 360 $this->assertEquals('0–100', $studentgrades['usergrades'][0]['gradeitems'][0]['rangeformatted']); 361 $this->assertEquals('80.00 %', $studentgrades['usergrades'][0]['gradeitems'][0]['percentageformatted']); 362 $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['feedback']); 363 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradehiddenbydate']); 364 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeneedsupdate']); 365 $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeishidden']); 366 $this->assertNull($studentgrades['usergrades'][0]['gradeitems'][0]['gradeislocked']); 367 $this->assertNull($studentgrades['usergrades'][0]['gradeitems'][0]['gradeisoverridden']); 368 $this->assertEquals('B-', $studentgrades['usergrades'][0]['gradeitems'][0]['lettergradeformatted']); 369 $this->assertEquals(1, $studentgrades['usergrades'][0]['gradeitems'][0]['rank']); 370 $this->assertEquals(2, $studentgrades['usergrades'][0]['gradeitems'][0]['numusers']); 371 $this->assertEquals(70, $studentgrades['usergrades'][0]['gradeitems'][0]['averageformatted']); 372 373 // Check that the idnumber for assignment grades is equal to the cmid. 374 $this->assertEquals((string) $studentgrades['usergrades'][0]['gradeitems'][0]['cmid'], 375 $studentgrades['usergrades'][0]['gradeitems'][0]['idnumber']); 376 377 // Hide one grade for the user. 378 $gradegrade = new \grade_grade(array('userid' => $student1->id, 379 'itemid' => $studentgrades['usergrades'][0]['gradeitems'][0]['id']), true); 380 $gradegrade->set_hidden(1); 381 $studentgrades = gradereport_user_external::get_grade_items($course->id, $student1->id); 382 $studentgrades = \external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); 383 384 // Check we get only the course final grade. 385 $this->assertCount(1, $studentgrades['usergrades']); 386 $this->assertCount(1, $studentgrades['usergrades'][0]['gradeitems']); 387 $this->assertEquals('course', $studentgrades['usergrades'][0]['gradeitems'][0]['itemtype']); 388 } 389 390 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body