Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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