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  /**
  18   * External rating functions unit tests
  19   *
  20   * @package    core_rating
  21   * @category   external
  22   * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace core_rating;
  27  
  28  use core_rating_external;
  29  use externallib_advanced_testcase;
  30  
  31  defined('MOODLE_INTERNAL') || die();
  32  
  33  global $CFG;
  34  
  35  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  36  require_once($CFG->dirroot . '/rating/lib.php');
  37  
  38  /**
  39   * External rating functions unit tests
  40   *
  41   * @package    core_rating
  42   * @category   external
  43   * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
  44   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  45   */
  46  class externallib_test extends externallib_advanced_testcase {
  47  
  48      /*
  49       * Set up for every test
  50       */
  51      public function setUp(): void {
  52          global $DB;
  53          $this->resetAfterTest();
  54  
  55          $this->course = self::getDataGenerator()->create_course();
  56          $this->student1 = $this->getDataGenerator()->create_user();
  57          $this->student2 = $this->getDataGenerator()->create_user();
  58          $this->teacher1 = $this->getDataGenerator()->create_user();
  59          $this->teacher2 = $this->getDataGenerator()->create_user();
  60          $this->teacher3 = $this->getDataGenerator()->create_user();
  61          $this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
  62          $this->teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
  63          unassign_capability('moodle/site:accessallgroups', $this->teacherrole->id);
  64  
  65          $this->getDataGenerator()->enrol_user($this->student1->id, $this->course->id, $this->studentrole->id);
  66          $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id);
  67          $this->getDataGenerator()->enrol_user($this->teacher1->id, $this->course->id, $this->teacherrole->id);
  68          $this->getDataGenerator()->enrol_user($this->teacher2->id, $this->course->id, $this->teacherrole->id);
  69          $this->getDataGenerator()->enrol_user($this->teacher3->id, $this->course->id, $this->teacherrole->id);
  70  
  71          // Create the forum.
  72          $record = new \stdClass();
  73          $record->introformat = FORMAT_HTML;
  74          $record->course = $this->course->id;
  75          // Set Aggregate type = Average of ratings.
  76          $record->assessed = RATING_AGGREGATE_AVERAGE;
  77          $record->scale = 100;
  78          $this->forum = self::getDataGenerator()->create_module('forum', $record);
  79  
  80          $this->contextid = \context_module::instance($this->forum->cmid)->id;
  81  
  82          // Add discussion to the forums.
  83          $record = new \stdClass();
  84          $record->course = $this->course->id;
  85          $record->userid = $this->student1->id;
  86          $record->forum = $this->forum->id;
  87          $this->discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
  88          // Retrieve the first post.
  89          $this->post = $DB->get_record('forum_posts', array('discussion' => $this->discussion->id));
  90      }
  91  
  92      /**
  93       * Test get_item_ratings
  94       */
  95      public function test_get_item_ratings() {
  96          global $DB;
  97  
  98          // Rete the discussion as teacher1.
  99          $rating1 = new \stdClass();
 100          $rating1->contextid = $this->contextid;
 101          $rating1->component = 'mod_forum';
 102          $rating1->ratingarea = 'post';
 103          $rating1->itemid = $this->post->id;
 104          $rating1->rating = 90;
 105          $rating1->scaleid = 100;
 106          $rating1->userid = $this->teacher1->id;
 107          $rating1->timecreated = time();
 108          $rating1->timemodified = time();
 109          $rating1->id = $DB->insert_record('rating', $rating1);
 110  
 111          // Rete the discussion as teacher2.
 112          $rating2 = new \stdClass();
 113          $rating2->contextid = $this->contextid;
 114          $rating2->component = 'mod_forum';
 115          $rating2->ratingarea = 'post';
 116          $rating2->itemid = $this->post->id;
 117          $rating2->rating = 95;
 118          $rating2->scaleid = 100;
 119          $rating2->userid = $this->teacher2->id;
 120          $rating2->timecreated = time() + 1;
 121          $rating2->timemodified = time() + 1;
 122          $rating2->id = $DB->insert_record('rating', $rating2);
 123  
 124          // Delete teacher2, we must still receive the ratings.
 125          delete_user($this->teacher2);
 126  
 127          // Teachers can see all the ratings.
 128          $this->setUser($this->teacher1);
 129  
 130          $ratings = core_rating_external::get_item_ratings('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100, '');
 131          // We need to execute the return values cleaning process to simulate the web service server.
 132          $ratings = \external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings);
 133          $this->assertCount(2, $ratings['ratings']);
 134  
 135          $indexedratings = array();
 136          foreach ($ratings['ratings'] as $rating) {
 137              $indexedratings[$rating['id']] = $rating;
 138          }
 139          $this->assertEquals($rating1->rating.' / '.$rating1->scaleid, $indexedratings[$rating1->id]['rating']);
 140          $this->assertEquals($rating2->rating.' / '.$rating2->scaleid, $indexedratings[$rating2->id]['rating']);
 141  
 142          $this->assertEquals($rating1->userid, $indexedratings[$rating1->id]['userid']);
 143          $this->assertEquals($rating2->userid, $indexedratings[$rating2->id]['userid']);
 144  
 145          // Student can see ratings.
 146          $this->setUser($this->student1);
 147  
 148          $ratings = core_rating_external::get_item_ratings('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100, '');
 149          // We need to execute the return values cleaning process to simulate the web service server.
 150          $ratings = \external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings);
 151          $this->assertCount(2, $ratings['ratings']);
 152  
 153          // Invalid item.
 154          try {
 155              $ratings = core_rating_external::get_item_ratings('module', $this->forum->cmid, 'mod_forum', 'post', 0, 100, '');
 156              $this->fail('Exception expected due invalid itemid.');
 157          } catch (\moodle_exception $e) {
 158              $this->assertEquals('invalidrecord', $e->errorcode);
 159          }
 160  
 161          // Invalid area.
 162          try {
 163              $ratings = core_rating_external::get_item_ratings('module', $this->forum->cmid, 'mod_forum', 'xyz', $this->post->id, 100, '');
 164              $this->fail('Exception expected due invalid rating area.');
 165          } catch (\moodle_exception $e) {
 166              $this->assertEquals('invalidratingarea', $e->errorcode);
 167          }
 168  
 169          // Invalid context. invalid_parameter_exception.
 170          try {
 171              $ratings = core_rating_external::get_item_ratings('module', 0, 'mod_forum', 'post', $this->post->id, 100, '');
 172              $this->fail('Exception expected due invalid context.');
 173          } catch (\invalid_parameter_exception $e) {
 174              $this->assertEquals('invalidparameter', $e->errorcode);
 175          }
 176  
 177          // Test for groupmode.
 178          set_coursemodule_groupmode($this->forum->cmid, SEPARATEGROUPS);
 179          $group = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
 180          groups_add_member($group, $this->teacher1);
 181  
 182          $this->discussion->groupid = $group->id;
 183          $DB->update_record('forum_discussions', $this->discussion);
 184  
 185          // Error for teacher3 and 2 ratings for teacher1 should be returned.
 186          $this->setUser($this->teacher1);
 187          $ratings = core_rating_external::get_item_ratings('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100, '');
 188          // We need to execute the return values cleaning process to simulate the web service server.
 189          $ratings = \external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings);
 190          $this->assertCount(2, $ratings['ratings']);
 191  
 192          $this->setUser($this->teacher3);
 193          try {
 194              $ratings = core_rating_external::get_item_ratings('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100, '');
 195              $this->fail('Exception expected due invalid group permissions.');
 196          } catch (\moodle_exception $e) {
 197              $this->assertEquals('noviewrate', $e->errorcode);
 198          }
 199  
 200      }
 201  
 202      /**
 203       * Test add_rating
 204       */
 205      public function test_add_rating() {
 206          $this->setUser($this->teacher1);
 207  
 208          // First rating of 50.
 209          $rating = core_rating_external::add_rating('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100,
 210                                                      50, $this->student1->id, RATING_AGGREGATE_AVERAGE);
 211          // We need to execute the return values cleaning process to simulate the web service server.
 212          $rating = \external_api::clean_returnvalue(core_rating_external::add_rating_returns(), $rating);
 213          $this->assertTrue($rating['success']);
 214          $this->assertEquals(50, $rating['aggregate']);
 215          $this->assertEquals(1, $rating['count']);
 216  
 217          // New different rate (it will replace the existing one).
 218          $rating = core_rating_external::add_rating('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100,
 219                                                      100, $this->student1->id, RATING_AGGREGATE_AVERAGE);
 220          $rating = \external_api::clean_returnvalue(core_rating_external::add_rating_returns(), $rating);
 221                  $this->assertTrue($rating['success']);
 222          $this->assertEquals(100, $rating['aggregate']);
 223          $this->assertEquals(1, $rating['count']);
 224  
 225          // Rate as other user.
 226          $this->setUser($this->teacher2);
 227          $rating = core_rating_external::add_rating('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100,
 228                                                      50, $this->student1->id, RATING_AGGREGATE_AVERAGE);
 229          $rating = \external_api::clean_returnvalue(core_rating_external::add_rating_returns(), $rating);
 230          $this->assertEquals(75, $rating['aggregate']);
 231          $this->assertEquals(2, $rating['count']);
 232  
 233          // Try to rate my own post.
 234          $this->setUser($this->student1);
 235          $this->expectException('moodle_exception');
 236          $this->expectExceptionMessage(get_string('ratepermissiondenied', 'rating'));
 237          $rating = core_rating_external::add_rating('module', $this->forum->cmid, 'mod_forum', 'post', $this->post->id, 100,
 238                                                          100, $this->student1->id, RATING_AGGREGATE_AVERAGE);
 239      }
 240  }