MDL-50173 ratings: Use proper checks to ensure ratings are viewable.
[moodle.git] / rating / tests / externallib_test.php
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/>.
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  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
30 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
31 require_once($CFG->dirroot . '/rating/lib.php');
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 {
43     /**
44      * Test get_item_ratings
45      */
46     public function test_get_item_ratings() {
48         global $DB, $USER;
50         $this->resetAfterTest(true);
52         $course = self::getDataGenerator()->create_course();
53         $student = $this->getDataGenerator()->create_user();
54         $teacher1 = $this->getDataGenerator()->create_user();
55         $teacher2 = $this->getDataGenerator()->create_user();
56         $teacher3 = $this->getDataGenerator()->create_user();
57         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
58         $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
59         unassign_capability('moodle/site:accessallgroups', $teacherrole->id);
61         $this->getDataGenerator()->enrol_user($student->id,  $course->id, $studentrole->id);
62         $this->getDataGenerator()->enrol_user($teacher1->id, $course->id, $teacherrole->id);
63         $this->getDataGenerator()->enrol_user($teacher2->id, $course->id, $teacherrole->id);
64         $this->getDataGenerator()->enrol_user($teacher3->id, $course->id, $teacherrole->id);
66         // Create the forum.
67         $record = new stdClass();
68         $record->introformat = FORMAT_HTML;
69         $record->course = $course->id;
70         // Set Aggregate type = Average of ratings.
71         $record->assessed = RATING_AGGREGATE_AVERAGE;
72         $forum = self::getDataGenerator()->create_module('forum', $record);
74         $contextid = context_module::instance($forum->cmid)->id;
76         // Add discussion to the forums.
77         $record = new stdClass();
78         $record->course = $course->id;
79         $record->userid = $student->id;
80         $record->forum = $forum->id;
81         $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
82         // Retrieve the first post.
83         $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
85         // Rete the discussion as teacher1.
86         $rating1 = new stdClass();
87         $rating1->contextid = $contextid;
88         $rating1->component = 'mod_forum';
89         $rating1->ratingarea = 'post';
90         $rating1->itemid = $post->id;
91         $rating1->rating = 90;
92         $rating1->scaleid = 100;
93         $rating1->userid = $teacher1->id;
94         $rating1->timecreated = time();
95         $rating1->timemodified = time();
96         $rating1->id = $DB->insert_record('rating', $rating1);
98         // Rete the discussion as teacher2.
99         $rating2 = new stdClass();
100         $rating2->contextid = $contextid;
101         $rating2->component = 'mod_forum';
102         $rating2->ratingarea = 'post';
103         $rating2->itemid = $post->id;
104         $rating2->rating = 95;
105         $rating2->scaleid = 100;
106         $rating2->userid = $teacher2->id;
107         $rating2->timecreated = time() + 1;
108         $rating2->timemodified = time() + 1;
109         $rating2->id = $DB->insert_record('rating', $rating2);
111         // Delete teacher2, we must still receive the ratings.
112         delete_user($teacher2);
114         // Teachers can see all the ratings.
115         $this->setUser($teacher1);
117         $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, '');
118         // We need to execute the return values cleaning process to simulate the web service server.
119         $ratings = external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings);
120         $this->assertCount(2, $ratings['ratings']);
122         $indexedratings = array();
123         foreach ($ratings['ratings'] as $rating) {
124             $indexedratings[$rating['id']] = $rating;
125         }
126         $this->assertEquals($rating1->rating.' / '.$rating1->scaleid, $indexedratings[$rating1->id]['rating']);
127         $this->assertEquals($rating2->rating.' / '.$rating2->scaleid, $indexedratings[$rating2->id]['rating']);
129         $this->assertEquals($rating1->userid, $indexedratings[$rating1->id]['userid']);
130         $this->assertEquals($rating2->userid, $indexedratings[$rating2->id]['userid']);
132         // Student can see ratings.
133         $this->setUser($student);
135         $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, '');
136         // We need to execute the return values cleaning process to simulate the web service server.
137         $ratings = external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings);
138         $this->assertCount(2, $ratings['ratings']);
140         // Invalid item.
141         try {
142             $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', 0, 100, '');
143             $this->fail('Exception expected due invalid itemid.');
144         } catch (moodle_exception $e) {
145             $this->assertEquals('invalidrecord', $e->errorcode);
146         }
148         // Invalid area.
149         try {
150             $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'xyz', $post->id, 100, '');
151             $this->fail('Exception expected due invalid rating area.');
152         } catch (moodle_exception $e) {
153             $this->assertEquals('invalidratingarea', $e->errorcode);
154         }
156         // Invalid context. invalid_parameter_exception.
157         try {
158             $ratings = core_rating_external::get_item_ratings('module', 0, 'mod_forum', 'post', $post->id, 100, '');
159             $this->fail('Exception expected due invalid context.');
160         } catch (invalid_parameter_exception $e) {
161             $this->assertEquals('invalidparameter', $e->errorcode);
162         }
164         // Test for groupmode.
165         set_coursemodule_groupmode($forum->cmid, SEPARATEGROUPS);
166         $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
167         groups_add_member($group, $teacher1);
169         $discussion->groupid = $group->id;
170         $DB->update_record('forum_discussions', $discussion);
172         // Error for teacher3 and 2 ratings for teacher1 should be returned.
173         $this->setUser($teacher1);
174         $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, '');
175         // We need to execute the return values cleaning process to simulate the web service server.
176         $ratings = external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings);
177         $this->assertCount(2, $ratings['ratings']);
179         $this->setUser($teacher3);
180         try {
181             $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, '');
182             $this->fail('Exception expected due invalid group permissions.');
183         } catch (moodle_exception $e) {
184             $this->assertEquals('noviewrate', $e->errorcode);
185         }
187     }