Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 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  /**
  18   * Unit tests for the class component_gradeitem.
  19   *
  20   * @package   core_grades
  21   * @category  test
  22   * @copyright 2021 Mark Nelson <marknelson@catalyst-au.net>
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU Public License
  24   */
  25  
  26  namespace core_grades;
  27  
  28  use advanced_testcase;
  29  use mod_forum\local\container;
  30  use mod_forum\local\entities\forum as forum_entity;
  31  
  32  defined('MOODLE_INTERNAL') || die();
  33  
  34  /**
  35   * Unit tests for the class component_gradeitem.
  36   *
  37   * @package   core_grades
  38   * @category  test
  39   * @copyright 2021 Mark Nelson <marknelson@catalyst-au.net>
  40   * @license   http://www.gnu.org/copyleft/gpl.html GNU Public License
  41   */
  42  class component_gradeitem_test extends advanced_testcase {
  43  
  44      /**
  45       * Test get_formatted_grade_for_user with points.
  46       */
  47      public function test_get_formatted_grade_for_user_with_points() {
  48          $grade = $this->initialise_test_and_get_grade_item(5, 4);
  49  
  50          $this->assertEquals(4, $grade->grade);
  51          $this->assertEquals('4.00 / 5.00', $grade->usergrade);
  52          $this->assertEquals(5, $grade->maxgrade);
  53      }
  54  
  55      /**
  56       * Test get_formatted_grade_for_user with letters.
  57       */
  58      public function test_get_formatted_grade_for_user_with_letters() {
  59          $grade = $this->initialise_test_and_get_grade_item(5, 4, GRADE_DISPLAY_TYPE_LETTER);
  60  
  61          $this->assertEquals(4, $grade->grade);
  62          $this->assertEquals('B-', $grade->usergrade);
  63          $this->assertEquals(5, $grade->maxgrade);
  64      }
  65  
  66      /**
  67       * Test get_formatted_grade_for_user with percentage.
  68       */
  69      public function test_get_formatted_grade_for_user_with_percentage() {
  70          $grade = $this->initialise_test_and_get_grade_item(5, 4, GRADE_DISPLAY_TYPE_PERCENTAGE);
  71  
  72          $this->assertEquals(4, $grade->grade);
  73          $this->assertEquals('80.00 %', $grade->usergrade);
  74          $this->assertEquals(5, $grade->maxgrade);
  75      }
  76  
  77      /**
  78       * Test get_formatted_grade_for_user with points and letter.
  79       */
  80      public function test_get_formatted_grade_for_user_with_points_letter() {
  81          $grade = $this->initialise_test_and_get_grade_item(5, 4, GRADE_DISPLAY_TYPE_REAL_LETTER);
  82  
  83          $this->assertEquals(4, $grade->grade);
  84          $this->assertEquals('4.00 (B-)', $grade->usergrade);
  85          $this->assertEquals(5, $grade->maxgrade);
  86      }
  87  
  88      /**
  89       * Test get_formatted_grade_for_user with scales.
  90       */
  91      public function test_get_formatted_grade_for_user_with_scales() {
  92          $grade = $this->initialise_test_and_get_grade_item(-2, 2);
  93  
  94          $this->assertEquals(2, $grade->grade);
  95          $this->assertEquals('Competent', $grade->usergrade);
  96          $this->assertEquals(2, $grade->maxgrade);
  97      }
  98  
  99      /**
 100       * Test get_formatted_grade_for_user with rubric.
 101       */
 102      public function test_get_formatted_grade_for_user_with_rubric() {
 103          $this->resetAfterTest();
 104  
 105          $generator = \testing_util::get_data_generator();
 106          $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
 107  
 108          $forum = $this->get_forum_instance();
 109          $course = $forum->get_course_record();
 110          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 111          $student = $this->getDataGenerator()->create_and_enrol($course);
 112  
 113          $this->setUser($teacher);
 114  
 115          $controller = $rubricgenerator->get_test_rubric($forum->get_context(), 'forum', 'forum');
 116  
 117          // In the situation of mod_forum this would be the id from forum_grades.
 118          $itemid = 1;
 119          $instance = $controller->create_instance($student->id, $itemid);
 120  
 121          $spellingscore = 1;
 122          $spellingremark = 'Too many mistakes. Please try again.';
 123          $picturescore = 2;
 124          $pictureremark = 'Great number of pictures. Well done.';
 125  
 126          $submissiondata = $rubricgenerator->get_test_form_data(
 127              $controller,
 128              (int) $student->id,
 129              $spellingscore,
 130              $spellingremark,
 131              $picturescore,
 132              $pictureremark
 133          );
 134  
 135          $gradeitem = component_gradeitem::instance('mod_forum', $forum->get_context(), 'forum');
 136          $gradeitem->store_grade_from_formdata($student, $teacher, (object) [
 137              'instanceid' => $instance->get_id(),
 138              'advancedgrading' => $submissiondata,
 139          ]);
 140  
 141          $this->setUser($student);
 142  
 143          $result = $gradeitem->get_formatted_grade_for_user($student, $teacher);
 144  
 145          $this->assertEquals(75, $result->grade);
 146          $this->assertEquals('75.00 / 100.00', $result->usergrade);
 147          $this->assertEquals(100, $result->maxgrade);
 148      }
 149  
 150      /**
 151       * Test get_formatted_grade_for_user with a marking guide.
 152       */
 153      public function test_get_formatted_grade_for_user_with_marking_guide() {
 154          $this->resetAfterTest();
 155  
 156          $generator = \testing_util::get_data_generator();
 157          $guidegenerator = $generator->get_plugin_generator('gradingform_guide');
 158  
 159          $forum = $this->get_forum_instance();
 160          $course = $forum->get_course_record();
 161          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 162          $student = $this->getDataGenerator()->create_and_enrol($course);
 163  
 164          $this->setUser($teacher);
 165  
 166          $controller = $guidegenerator->get_test_guide($forum->get_context(), 'forum', 'forum');
 167  
 168          // In the situation of mod_forum this would be the id from forum_grades.
 169          $itemid = 1;
 170          $instance = $controller->create_instance($student->id, $itemid);
 171  
 172          $spellingscore = 10;
 173          $spellingremark = 'Propper good speling';
 174          $picturescore = 0;
 175          $pictureremark = 'ASCII art is not a picture';
 176  
 177          $submissiondata = $guidegenerator->get_test_form_data($controller,
 178              $itemid,
 179              $spellingscore,
 180              $spellingremark,
 181              $picturescore,
 182              $pictureremark
 183          );
 184  
 185          $gradeitem = component_gradeitem::instance('mod_forum', $forum->get_context(), 'forum');
 186          $gradeitem->store_grade_from_formdata($student, $teacher, (object) [
 187              'instanceid' => $instance->get_id(),
 188              'advancedgrading' => $submissiondata,
 189          ]);
 190  
 191          $this->setUser($student);
 192  
 193          $result = $gradeitem->get_formatted_grade_for_user($student, $teacher);
 194  
 195          $this->assertEquals(25, $result->grade);
 196          $this->assertEquals('25.00 / 100.00', $result->usergrade);
 197          $this->assertEquals(100, $result->maxgrade);
 198      }
 199  
 200      /**
 201       * Initialise test and returns the grade item.
 202       *
 203       * @param int $gradeforum The grade_forum value for the forum.
 204       * @param int $gradegiven The grade given by the teacher.
 205       * @param int|null $displaytype The display type of the grade.
 206       * @return \stdClass|null
 207       */
 208      protected function initialise_test_and_get_grade_item(int $gradeforum, int $gradegiven, int $displaytype = null): \stdClass {
 209          $this->resetAfterTest();
 210  
 211          $forum = $this->get_forum_instance([
 212              // Negative numbers mean a scale, positive numbers represent the maximum mark.
 213              'grade_forum' => $gradeforum,
 214          ]);
 215          $course = $forum->get_course_record();
 216          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 217          $student = $this->getDataGenerator()->create_and_enrol($course);
 218  
 219          $this->setUser($teacher);
 220  
 221          // Get the grade item.
 222          $gradeitem = component_gradeitem::instance('mod_forum', $forum->get_context(), 'forum');
 223  
 224          // Grade the student.
 225          $gradeitem->store_grade_from_formdata($student, $teacher, (object) ['grade' => $gradegiven]);
 226  
 227          // Change the 'Grade display type' if specified.
 228          if ($displaytype) {
 229              grade_set_setting($course->id, 'displaytype', $displaytype);
 230          }
 231  
 232          return $gradeitem->get_formatted_grade_for_user($student, $teacher);
 233      }
 234  
 235      /**
 236       * Get a forum instance.
 237       *
 238       * @param array $config
 239       * @return forum_entity
 240       */
 241      protected function get_forum_instance(array $config = []): forum_entity {
 242          $this->resetAfterTest();
 243  
 244          $datagenerator = $this->getDataGenerator();
 245          $course = $datagenerator->create_course();
 246          $forum = $datagenerator->create_module('forum', array_merge(['course' => $course->id,
 247              'grade_forum' => 100], $config));
 248  
 249          $vaultfactory = container::get_vault_factory();
 250          $vault = $vaultfactory->get_forum_vault();
 251  
 252          return $vault->get_from_id((int) $forum->id);
 253      }
 254  }