Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 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 gradereport_overview;
  18  
  19  use externallib_advanced_testcase;
  20  use gradereport_overview_external;
  21  
  22  defined('MOODLE_INTERNAL') || die();
  23  
  24  global $CFG;
  25  
  26  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  27  
  28  /**
  29   * Overview grade report functions unit tests
  30   *
  31   * @package    gradereport_overview
  32   * @category   external
  33   * @copyright  2015 Juan Leyva <juan@moodle.com>
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class externallib_test extends externallib_advanced_testcase {
  37  
  38      /**
  39       * Set up for every test
  40       */
  41      public function setUp(): void {
  42          global $DB;
  43          $this->resetAfterTest(true);
  44  
  45          $s1grade1 = 80;
  46          $s1grade2 = 40;
  47          $s2grade = 60;
  48  
  49          $this->course1 = $this->getDataGenerator()->create_course();
  50          $this->course2 = $this->getDataGenerator()->create_course();
  51  
  52          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
  53          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
  54          $this->student1 = $this->getDataGenerator()->create_user();
  55          $this->teacher = $this->getDataGenerator()->create_user();
  56          $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course1->id, $teacherrole->id);
  57          $this->getDataGenerator()->enrol_user($this->student1->id, $this->course1->id, $studentrole->id);
  58          $this->getDataGenerator()->enrol_user($this->student1->id, $this->course2->id, $studentrole->id);
  59  
  60          $this->student2 = $this->getDataGenerator()->create_user();
  61          $this->getDataGenerator()->enrol_user($this->student2->id, $this->course1->id, $studentrole->id);
  62          $this->getDataGenerator()->enrol_user($this->student2->id, $this->course2->id, $studentrole->id);
  63  
  64          $assignment1 = $this->getDataGenerator()->create_module('assign', array('name' => "Test assign", 'course' => $this->course1->id));
  65          $assignment2 = $this->getDataGenerator()->create_module('assign', array('name' => "Test assign", 'course' => $this->course2->id));
  66          $modcontext1 = get_coursemodule_from_instance('assign', $assignment1->id, $this->course1->id);
  67          $modcontext2 = get_coursemodule_from_instance('assign', $assignment2->id, $this->course2->id);
  68          $assignment1->cmidnumber = $modcontext1->id;
  69          $assignment2->cmidnumber = $modcontext2->id;
  70  
  71          $this->student1grade1 = array('userid' => $this->student1->id, 'rawgrade' => $s1grade1);
  72          $this->student1grade2 = array('userid' => $this->student1->id, 'rawgrade' => $s1grade2);
  73          $this->student2grade = array('userid' => $this->student2->id, 'rawgrade' => $s2grade);
  74          $studentgrades = array($this->student1->id => $this->student1grade1, $this->student2->id => $this->student2grade);
  75          assign_grade_item_update($assignment1, $studentgrades);
  76          $studentgrades = array($this->student1->id => $this->student1grade2);
  77          assign_grade_item_update($assignment2, $studentgrades);
  78  
  79          grade_get_setting($this->course1->id, 'report_overview_showrank', 1);
  80      }
  81  
  82      /**
  83       * Test get_course_grades function case student
  84       */
  85      public function test_get_course_grades_student() {
  86  
  87          // A user can see his own grades in both courses.
  88          $this->setUser($this->student1);
  89          $studentgrades = gradereport_overview_external::get_course_grades();
  90          $studentgrades = \external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
  91  
  92          $this->assertCount(0, $studentgrades['warnings']);
  93          $this->assertCount(2, $studentgrades['grades']);
  94          foreach ($studentgrades['grades'] as $grade) {
  95              if ($grade['courseid'] == $this->course1->id) {
  96                  $this->assertEquals(80.00, $grade['grade']);
  97                  $this->assertEquals(80.0000, $grade['rawgrade']);
  98                  $this->assertEquals(1, $grade['rank']);
  99              } else {
 100                  $this->assertEquals(40.00, $grade['grade']);
 101                  $this->assertEquals(40.0000, $grade['rawgrade']);
 102                  $this->assertArrayNotHasKey('rank', $grade);
 103              }
 104          }
 105  
 106          // Second student, no grade in one course.
 107          $this->setUser($this->student2);
 108          $studentgrades = gradereport_overview_external::get_course_grades();
 109          $studentgrades = \external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
 110  
 111          $this->assertCount(0, $studentgrades['warnings']);
 112          $this->assertCount(2, $studentgrades['grades']);
 113          foreach ($studentgrades['grades'] as $grade) {
 114              if ($grade['courseid'] == $this->course1->id) {
 115                  $this->assertEquals(60.00, $grade['grade']);
 116                  $this->assertEquals(60.0000, $grade['rawgrade']);
 117                  $this->assertEquals(2, $grade['rank']);
 118              } else {
 119                  $this->assertEquals('-', $grade['grade']);
 120                  $this->assertEmpty($grade['rawgrade']);
 121                  $this->assertArrayNotHasKey('rank', $grade);
 122              }
 123          }
 124      }
 125  
 126      /**
 127       * Test get_course_grades function case admin
 128       */
 129      public function test_get_course_grades_admin() {
 130  
 131          // A admin must see all student grades.
 132          $this->setAdminUser();
 133  
 134          $studentgrades = gradereport_overview_external::get_course_grades($this->student1->id);
 135          $studentgrades = \external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
 136          $this->assertCount(0, $studentgrades['warnings']);
 137          $this->assertCount(2, $studentgrades['grades']);
 138          foreach ($studentgrades['grades'] as $grade) {
 139              if ($grade['courseid'] == $this->course1->id) {
 140                  $this->assertEquals(80.00, $grade['grade']);
 141                  $this->assertEquals(80.0000, $grade['rawgrade']);
 142              } else {
 143                  $this->assertEquals(40.00, $grade['grade']);
 144                  $this->assertEquals(40.0000, $grade['rawgrade']);
 145              }
 146          }
 147  
 148          $studentgrades = gradereport_overview_external::get_course_grades($this->student2->id);
 149          $studentgrades = \external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
 150          $this->assertCount(0, $studentgrades['warnings']);
 151          $this->assertCount(2, $studentgrades['grades']);
 152  
 153          // Admins don't see grades.
 154          $studentgrades = gradereport_overview_external::get_course_grades();
 155          $studentgrades = \external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
 156          $this->assertCount(0, $studentgrades['warnings']);
 157          $this->assertCount(0, $studentgrades['grades']);
 158      }
 159  
 160      /**
 161       * Test get_course_grades function case teacher
 162       */
 163      public function test_get_course_grades_teacher() {
 164          // Teachers don't see grades.
 165          $this->setUser($this->teacher);
 166  
 167          $studentgrades = gradereport_overview_external::get_course_grades();
 168          $studentgrades = \external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
 169          $this->assertCount(0, $studentgrades['warnings']);
 170          $this->assertCount(0, $studentgrades['grades']);
 171      }
 172  
 173      /**
 174       * Test get_course_grades function case incorrect permissions
 175       */
 176      public function test_get_course_grades_permissions() {
 177          // Student can't see other student grades.
 178          $this->setUser($this->student2);
 179  
 180          $this->expectException('required_capability_exception');
 181          $studentgrade = gradereport_overview_external::get_course_grades($this->student1->id);
 182      }
 183  
 184      /**
 185       * Test view_grade_report function
 186       */
 187      public function test_view_grade_report() {
 188          global $USER;
 189  
 190          // Redirect events to the sink, so we can recover them later.
 191          $sink = $this->redirectEvents();
 192  
 193          $this->setUser($this->student1);
 194          $result = gradereport_overview_external::view_grade_report($this->course1->id);
 195          $result = \external_api::clean_returnvalue(gradereport_overview_external::view_grade_report_returns(), $result);
 196          $events = $sink->get_events();
 197          $this->assertCount(1, $events);
 198          $event = reset($events);
 199  
 200          // Check the event details are correct.
 201          $this->assertInstanceOf('\gradereport_overview\event\grade_report_viewed', $event);
 202          $this->assertEquals(\context_course::instance($this->course1->id), $event->get_context());
 203          $this->assertEquals($USER->id, $event->get_data()['relateduserid']);
 204  
 205          $this->setUser($this->teacher);
 206          $result = gradereport_overview_external::view_grade_report($this->course1->id, $this->student1->id);
 207          $result = \external_api::clean_returnvalue(gradereport_overview_external::view_grade_report_returns(), $result);
 208          $events = $sink->get_events();
 209          $event = reset($events);
 210          $sink->close();
 211  
 212          // Check the event details are correct.
 213          $this->assertInstanceOf('\gradereport_overview\event\grade_report_viewed', $event);
 214          $this->assertEquals(\context_course::instance($this->course1->id), $event->get_context());
 215          $this->assertEquals($this->student1->id, $event->get_data()['relateduserid']);
 216      }
 217  
 218      /**
 219       * Test view_grade_report_permissions function
 220       */
 221      public function test_view_grade_report_permissions() {
 222          $this->setUser($this->student2);
 223  
 224          $this->expectException('moodle_exception');
 225          $studentgrade = gradereport_overview_external::view_grade_report($this->course1->id, $this->student1->id);
 226      }
 227  }