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] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

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