2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Unit tests for rating/lib.php
20 * @package core_ratings
22 * @copyright 2011 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
28 // Include all the needed stuff
30 require_once($CFG->dirroot
. '/rating/lib.php');
34 * Unit test case for all the rating/lib.php requiring DB mockup & manipulation
36 class core_rating_testcase
extends advanced_testcase
{
38 protected $syscontext;
39 protected $neededcaps = array('view', 'viewall', 'viewany', 'rate');
40 protected $originaldefaultfrontpageroleid;
42 public function setUp() {
46 $this->resetAfterTest(true);
48 $CFG->defaultfrontpageroleid
= null;
52 * Test the current get_ratings method main sql
54 function test_get_ratings_sql() {
57 // We load 3 items. Each is rated twice. For simplicity itemid == user id of the item owner
58 $ctxid = context_system
::instance()->id
;
60 //user 1's items. Average == 2
61 array('contextid'=>$ctxid ,'component'=>'mod_forum','ratingarea'=>'post','itemid'=>1 ,'scaleid'=>10 ,'rating'=>1 ,'userid'=>2 ,'timecreated'=>1 ,'timemodified'=>1),
62 array('contextid'=>$ctxid ,'component'=>'mod_forum','ratingarea'=>'post','itemid'=>1 ,'scaleid'=>10 ,'rating'=>3 ,'userid'=>3 ,'timecreated'=>1 ,'timemodified'=>1),
63 //user 2's items. Average == 3
64 array('contextid'=>$ctxid ,'component'=>'mod_forum','ratingarea'=>'post','itemid'=>2 ,'scaleid'=>10 ,'rating'=>1 ,'userid'=>1 ,'timecreated'=>1 ,'timemodified'=>1),
65 array('contextid'=>$ctxid ,'component'=>'mod_forum','ratingarea'=>'post','itemid'=>2 ,'scaleid'=>10 ,'rating'=>5 ,'userid'=>3 ,'timecreated'=>1 ,'timemodified'=>1),
66 //user 3's items. Average == 4
67 array('contextid'=>$ctxid ,'component'=>'mod_forum','ratingarea'=>'post','itemid'=>3 ,'scaleid'=>10 ,'rating'=>3 ,'userid'=>1 ,'timecreated'=>1 ,'timemodified'=>1),
68 array('contextid'=>$ctxid ,'component'=>'mod_forum','ratingarea'=>'post','itemid'=>3 ,'scaleid'=>10 ,'rating'=>5 ,'userid'=>2 ,'timecreated'=>1 ,'timemodified'=>1)
70 foreach ($ratings as $rating) {
71 $DB->insert_record('rating', $rating);
75 // a post (item) by user 1 (rated above by user 2 and 3 with average = 2)
77 (object)array('id' => 1, 'userid' => 1, 'message' => 'hello'));
78 // a post (item) by user 2 (rated above by user 1 and 3 with average = 3)
80 (object)array('id' => 2, 'userid' => 2, 'message' => 'world'));
81 // a post (item) by user 3 (rated above by user 1 and 2 with average = 4)
83 (object)array('id' => 3, 'userid' => 3, 'message' => 'moodle'));
85 // Prepare the default options
86 $defaultoptions = array (
87 'context' => context_system
::instance(),
88 'component' => 'mod_forum',
89 'ratingarea' => 'post',
91 'aggregate' => RATING_AGGREGATE_AVERAGE
);
93 $rm = new mockup_rating_manager();
95 // STEP 1: Retreive ratings using the current user
97 // Get results for user 1's item (expected average 1 + 3 / 2 = 2)
98 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts));
99 $result = $rm->get_ratings($toptions);
100 $this->assertEquals(count($result), count($user1posts));
101 $this->assertEquals($result[0]->id
, $user1posts[0]->id
);
102 $this->assertEquals($result[0]->userid
, $user1posts[0]->userid
);
103 $this->assertEquals($result[0]->message
, $user1posts[0]->message
);
104 $this->assertEquals($result[0]->rating
->count
, 2);
105 $this->assertEquals($result[0]->rating
->aggregate
, 2);
106 // Note that $result[0]->rating->rating is somewhat random
107 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
109 // Get results for items of user 2 (expected average 1 + 5 / 2 = 3)
110 $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts));
111 $result = $rm->get_ratings($toptions);
112 $this->assertEquals(count($result), count($user2posts));
113 $this->assertEquals($result[0]->id
, $user2posts[0]->id
);
114 $this->assertEquals($result[0]->userid
, $user2posts[0]->userid
);
115 $this->assertEquals($result[0]->message
, $user2posts[0]->message
);
116 $this->assertEquals($result[0]->rating
->count
, 2);
117 $this->assertEquals($result[0]->rating
->aggregate
, 3);
118 // Note that $result[0]->rating->rating is somewhat random
119 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
121 // Get results for items of user 3 (expected average 3 + 5 / 2 = 4)
122 $toptions = (object)array_merge($defaultoptions, array('items' => $user3posts));
123 $result = $rm->get_ratings($toptions);
124 $this->assertEquals(count($result), count($user3posts));
125 $this->assertEquals($result[0]->id
, $user3posts[0]->id
);
126 $this->assertEquals($result[0]->userid
, $user3posts[0]->userid
);
127 $this->assertEquals($result[0]->message
, $user3posts[0]->message
);
128 $this->assertEquals($result[0]->rating
->count
, 2);
129 $this->assertEquals($result[0]->rating
->aggregate
, 4);
130 // Note that $result[0]->rating->rating is somewhat random
131 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
133 // Get results for items of user 1 & 2 together (expected averages are 2 and 3, as tested above)
134 $posts = array_merge($user1posts, $user2posts);
135 $toptions = (object)array_merge($defaultoptions, array('items' => $posts));
136 $result = $rm->get_ratings($toptions);
137 $this->assertEquals(count($result), count($posts));
138 $this->assertEquals($result[0]->id
, $posts[0]->id
);
139 $this->assertEquals($result[0]->userid
, $posts[0]->userid
);
140 $this->assertEquals($result[0]->message
, $posts[0]->message
);
141 $this->assertEquals($result[0]->rating
->count
, 2);
142 $this->assertEquals($result[0]->rating
->aggregate
, 2);
143 // Note that $result[0]->rating->rating is somewhat random
144 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
146 $this->assertEquals($result[1]->id
, $posts[1]->id
);
147 $this->assertEquals($result[1]->userid
, $posts[1]->userid
);
148 $this->assertEquals($result[1]->message
, $posts[1]->message
);
149 $this->assertEquals($result[1]->rating
->count
, 2);
150 $this->assertEquals($result[1]->rating
->aggregate
, 3);
151 // Note that $result[0]->rating->rating is somewhat random
152 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
154 // STEP 2: Retrieve ratings by a specified user
155 // We still expect complete aggregations and counts
157 // Get results for items of user 1 rated by user 2 (avg 2, rating 1)
158 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 2));
159 $result = $rm->get_ratings($toptions);
160 $this->assertEquals(count($result), count($user1posts));
161 $this->assertEquals($result[0]->id
, $user1posts[0]->id
);
162 $this->assertEquals($result[0]->userid
, $user1posts[0]->userid
);
163 $this->assertEquals($result[0]->message
, $user1posts[0]->message
);
164 $this->assertEquals($result[0]->rating
->count
, 2);
165 $this->assertEquals($result[0]->rating
->aggregate
, 2);
166 $this->assertEquals($result[0]->rating
->rating
, 1); //user 2 rated user 1 "1"
167 $this->assertEquals($result[0]->rating
->userid
, $toptions->userid
); // Must be the passed userid
169 // Get results for items of user 1 rated by user 3
170 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 3));
171 $result = $rm->get_ratings($toptions);
172 $this->assertEquals(count($result), count($user1posts));
173 $this->assertEquals($result[0]->id
, $user1posts[0]->id
);
174 $this->assertEquals($result[0]->userid
, $user1posts[0]->userid
);
175 $this->assertEquals($result[0]->message
, $user1posts[0]->message
);
176 $this->assertEquals($result[0]->rating
->count
, 2);
177 $this->assertEquals($result[0]->rating
->aggregate
, 2);
178 $this->assertEquals($result[0]->rating
->rating
, 3); //user 3 rated user 1 "3"
179 $this->assertEquals($result[0]->rating
->userid
, $toptions->userid
); // Must be the passed userid
181 // Get results for items of user 1 & 2 together rated by user 3
182 $posts = array_merge($user1posts, $user2posts);
183 $toptions = (object)array_merge($defaultoptions, array('items' => $posts, 'userid' => 3));
184 $result = $rm->get_ratings($toptions);
185 $this->assertEquals(count($result), count($posts));
186 $this->assertEquals($result[0]->id
, $posts[0]->id
);
187 $this->assertEquals($result[0]->userid
, $posts[0]->userid
);
188 $this->assertEquals($result[0]->message
, $posts[0]->message
);
189 $this->assertEquals($result[0]->rating
->count
, 2);
190 $this->assertEquals($result[0]->rating
->aggregate
, 2);
191 $this->assertEquals($result[0]->rating
->rating
, 3); //user 3 rated user 1 "3"
192 $this->assertEquals($result[0]->rating
->userid
, $toptions->userid
); // Must be the passed userid
194 $this->assertEquals($result[1]->id
, $posts[1]->id
);
195 $this->assertEquals($result[1]->userid
, $posts[1]->userid
);
196 $this->assertEquals($result[1]->message
, $posts[1]->message
);
197 $this->assertEquals($result[1]->rating
->count
, 2);
198 $this->assertEquals($result[1]->rating
->aggregate
, 3);
199 $this->assertEquals($result[0]->rating
->rating
, 3); //user 3 rated user 2 "5"
200 $this->assertEquals($result[1]->rating
->userid
, $toptions->userid
); // Must be the passed userid
202 // STEP 3: Some special cases
204 // Get results for user 1's items (expected average 1 + 3 / 2 = 2)
205 // supplying a non-existent user id so no rating from that user should be found
206 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts));
207 $toptions->userid
= 123456; //non-existent user
208 $result = $rm->get_ratings($toptions);
209 $this->assertNull($result[0]->rating
->userid
);
210 $this->assertNull($result[0]->rating
->rating
);
211 $this->assertEquals($result[0]->rating
->aggregate
, 2);//should still get the aggregate
213 // Get results for items of user 2 (expected average 1 + 5 / 2 = 3)
214 // Supplying the user id of the user who owns the items so no rating should be found
215 $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts));
216 $toptions->userid
= 2; //user 2 viewing the ratings of their own item
217 $result = $rm->get_ratings($toptions);
218 //these should be null as the user is viewing their own item and thus cannot rate
219 $this->assertNull($result[0]->rating
->userid
);
220 $this->assertNull($result[0]->rating
->rating
);
221 $this->assertEquals($result[0]->rating
->aggregate
, 3);//should still get the aggregate
226 * rating_manager subclass for unit testing without requiring capabilities to be loaded
228 class mockup_rating_manager
extends rating_manager
{
231 * Overwrite get_plugin_permissions_array() so it always return granted perms for unit testing
233 public function get_plugin_permissions_array($contextid, $component, $ratingarea) {