Commit | Line | Data |
---|---|---|
d8c71388 EL |
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 rating/lib.php | |
19 | * | |
20 | * @package moodlecore | |
21 | * @subpackage rating | |
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 | |
24 | */ | |
25 | ||
26 | defined('MOODLE_INTERNAL') || die(); | |
27 | ||
28 | // Include all the needed stuff | |
29 | require_once($CFG->dirroot . '/rating/lib.php'); | |
30 | ||
31 | /** | |
32 | * Unit test case for all the rating/lib.php requiring DB mockup & manipulation | |
33 | */ | |
34 | class rating_db_test extends UnitTestCaseUsingDatabase { | |
35 | ||
36 | public static $includecoverage = array( | |
37 | 'rating/lib.php' | |
38 | ); | |
39 | ||
40 | protected $testtables = array( | |
41 | 'lib' => array( | |
e437d9f1 EL |
42 | 'rating', 'scale', 'context', 'capabilities', 'role_assignments', 'role_capabilities', 'course')); |
43 | ||
44 | protected $syscontext; | |
45 | protected $neededcaps = array('view', 'viewall', 'viewany', 'rate'); | |
46 | protected $originaldefaultfrontpageroleid; | |
d8c71388 EL |
47 | |
48 | public function setUp() { | |
e437d9f1 | 49 | global $CFG; |
d8c71388 EL |
50 | parent::setUp(); |
51 | ||
e437d9f1 EL |
52 | // Make sure accesslib has cached a sensible system context object |
53 | // before we switch to the test DB. | |
54 | $this->syscontext = get_context_instance(CONTEXT_SYSTEM); | |
d8c71388 EL |
55 | |
56 | foreach ($this->testtables as $dir => $tables) { | |
57 | $this->create_test_tables($tables, $dir); // Create tables | |
58 | } | |
e437d9f1 EL |
59 | |
60 | $this->switch_to_test_db(); // Switch to test DB for all the execution | |
61 | ||
62 | $this->fill_records(); | |
63 | ||
64 | // Ignore any frontpageroleid, that would require to crete more contexts | |
65 | $this->originaldefaultfrontpageroleid = $CFG->defaultfrontpageroleid; | |
66 | $CFG->defaultfrontpageroleid = null; | |
67 | } | |
68 | ||
69 | public function tearDown() { | |
70 | global $CFG; | |
71 | // Recover original frontpageroleid | |
72 | $CFG->defaultfrontpageroleid = $this->originaldefaultfrontpageroleid; | |
73 | parent::tearDown(); | |
74 | } | |
75 | ||
76 | private function fill_records() { | |
77 | global $DB; | |
78 | ||
79 | // Set up systcontext in the test database. | |
80 | $this->syscontext->id = $this->testdb->insert_record('context', $this->syscontext); | |
81 | ||
82 | // Add the capabilities used by ratings | |
83 | foreach ($this->neededcaps as $neededcap) { | |
84 | $this->testdb->insert_record('capabilities', (object)array('name' => 'moodle/rating:' . $neededcap, | |
85 | 'contextlevel' => CONTEXT_COURSE)); | |
86 | } | |
d8c71388 EL |
87 | } |
88 | ||
89 | /** | |
90 | * Test the current get_ratings method main sql | |
91 | */ | |
92 | function test_get_ratings_sql() { | |
93 | ||
a924c53e | 94 | // We load 3 items. Each is rated twice. For simplicity itemid == user id of the item owner |
e437d9f1 | 95 | $ctxid = $this->syscontext->id; |
d8c71388 EL |
96 | $this->load_test_data('rating', |
97 | array('contextid', 'component', 'ratingarea', 'itemid', 'scaleid', 'rating', 'userid', 'timecreated', 'timemodified'), array( | |
a924c53e AD |
98 | |
99 | //user 1's items. Average == 2 | |
d8c71388 | 100 | array( $ctxid , 'mod_forum', 'post', 1 , 10 , 1 , 2 , 1 , 1), |
d8c71388 | 101 | array( $ctxid , 'mod_forum', 'post', 1 , 10 , 3 , 3 , 1 , 1), |
d8c71388 | 102 | |
a924c53e AD |
103 | //user 2's items. Average == 3 |
104 | array( $ctxid , 'mod_forum', 'post', 2 , 10 , 1 , 1 , 1 , 1), | |
105 | array( $ctxid , 'mod_forum', 'post', 2 , 10 , 5 , 3 , 1 , 1), | |
106 | ||
107 | //user 3's items. Average == 4 | |
108 | array( $ctxid , 'mod_forum', 'post', 3 , 10 , 3 , 1 , 1 , 1), | |
109 | array( $ctxid , 'mod_forum', 'post', 3 , 10 , 5 , 2 , 1 , 1) | |
110 | )); | |
111 | ||
112 | // a post (item) by user 1 (rated above by user 2 and 3 with average = 2) | |
d8c71388 EL |
113 | $user1posts = array( |
114 | (object)array('id' => 1, 'userid' => 1, 'message' => 'hello')); | |
a924c53e | 115 | // a post (item) by user 2 (rated above by user 1 and 3 with average = 3) |
d8c71388 EL |
116 | $user2posts = array( |
117 | (object)array('id' => 2, 'userid' => 2, 'message' => 'world')); | |
a924c53e | 118 | // a post (item) by user 3 (rated above by user 1 and 2 with average = 4) |
d8c71388 EL |
119 | $user3posts = array( |
120 | (object)array('id' => 3, 'userid' => 3, 'message' => 'moodle')); | |
121 | ||
122 | // Prepare the default options | |
123 | $defaultoptions = array ( | |
e437d9f1 | 124 | 'context' => $this->syscontext, |
d8c71388 EL |
125 | 'component' => 'mod_forum', |
126 | 'ratingarea' => 'post', | |
127 | 'scaleid' => 10, | |
128 | 'aggregate' => RATING_AGGREGATE_AVERAGE); | |
129 | ||
e437d9f1 | 130 | $rm = new mockup_rating_manager(); |
d8c71388 | 131 | |
a924c53e | 132 | // STEP 1: Retreive ratings using the current user |
d8c71388 | 133 | |
a924c53e | 134 | // Get results for user 1's item (expected average 1 + 3 / 2 = 2) |
d8c71388 EL |
135 | $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts)); |
136 | $result = $rm->get_ratings($toptions); | |
137 | $this->assertEqual(count($result), count($user1posts)); | |
138 | $this->assertEqual($result[0]->id, $user1posts[0]->id); | |
139 | $this->assertEqual($result[0]->userid, $user1posts[0]->userid); | |
140 | $this->assertEqual($result[0]->message, $user1posts[0]->message); | |
141 | $this->assertEqual($result[0]->rating->count, 2); | |
142 | $this->assertEqual($result[0]->rating->aggregate, 2); | |
a924c53e AD |
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 | |
d8c71388 EL |
145 | |
146 | // Get results for items of user 2 (expected average 1 + 5 / 2 = 3) | |
147 | $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts)); | |
148 | $result = $rm->get_ratings($toptions); | |
149 | $this->assertEqual(count($result), count($user2posts)); | |
150 | $this->assertEqual($result[0]->id, $user2posts[0]->id); | |
151 | $this->assertEqual($result[0]->userid, $user2posts[0]->userid); | |
152 | $this->assertEqual($result[0]->message, $user2posts[0]->message); | |
153 | $this->assertEqual($result[0]->rating->count, 2); | |
154 | $this->assertEqual($result[0]->rating->aggregate, 3); | |
a924c53e AD |
155 | // Note that $result[0]->rating->rating is somewhat random |
156 | // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests | |
d8c71388 EL |
157 | |
158 | // Get results for items of user 3 (expected average 3 + 5 / 2 = 4) | |
159 | $toptions = (object)array_merge($defaultoptions, array('items' => $user3posts)); | |
160 | $result = $rm->get_ratings($toptions); | |
161 | $this->assertEqual(count($result), count($user3posts)); | |
162 | $this->assertEqual($result[0]->id, $user3posts[0]->id); | |
163 | $this->assertEqual($result[0]->userid, $user3posts[0]->userid); | |
164 | $this->assertEqual($result[0]->message, $user3posts[0]->message); | |
165 | $this->assertEqual($result[0]->rating->count, 2); | |
166 | $this->assertEqual($result[0]->rating->aggregate, 4); | |
a924c53e AD |
167 | // Note that $result[0]->rating->rating is somewhat random |
168 | // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests | |
d8c71388 EL |
169 | |
170 | // Get results for items of user 1 & 2 together (expected averages are 2 and 3, as tested above) | |
171 | $posts = array_merge($user1posts, $user2posts); | |
172 | $toptions = (object)array_merge($defaultoptions, array('items' => $posts)); | |
173 | $result = $rm->get_ratings($toptions); | |
174 | $this->assertEqual(count($result), count($posts)); | |
175 | $this->assertEqual($result[0]->id, $posts[0]->id); | |
176 | $this->assertEqual($result[0]->userid, $posts[0]->userid); | |
177 | $this->assertEqual($result[0]->message, $posts[0]->message); | |
178 | $this->assertEqual($result[0]->rating->count, 2); | |
179 | $this->assertEqual($result[0]->rating->aggregate, 2); | |
a924c53e AD |
180 | // Note that $result[0]->rating->rating is somewhat random |
181 | // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests | |
d8c71388 EL |
182 | |
183 | $this->assertEqual($result[1]->id, $posts[1]->id); | |
184 | $this->assertEqual($result[1]->userid, $posts[1]->userid); | |
185 | $this->assertEqual($result[1]->message, $posts[1]->message); | |
186 | $this->assertEqual($result[1]->rating->count, 2); | |
187 | $this->assertEqual($result[1]->rating->aggregate, 3); | |
a924c53e AD |
188 | // Note that $result[0]->rating->rating is somewhat random |
189 | // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests | |
d8c71388 | 190 | |
a924c53e AD |
191 | // STEP 2: Retrieve ratings by a specified user |
192 | // We still expect complete aggregations and counts | |
d8c71388 | 193 | |
a924c53e | 194 | // Get results for items of user 1 rated by user 2 (avg 2, rating 1) |
d8c71388 EL |
195 | $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 2)); |
196 | $result = $rm->get_ratings($toptions); | |
197 | $this->assertEqual(count($result), count($user1posts)); | |
198 | $this->assertEqual($result[0]->id, $user1posts[0]->id); | |
199 | $this->assertEqual($result[0]->userid, $user1posts[0]->userid); | |
200 | $this->assertEqual($result[0]->message, $user1posts[0]->message); | |
201 | $this->assertEqual($result[0]->rating->count, 2); | |
202 | $this->assertEqual($result[0]->rating->aggregate, 2); | |
a924c53e | 203 | $this->assertEqual($result[0]->rating->rating, 1); //user 2 rated user 1 "1" |
d8c71388 EL |
204 | $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid |
205 | ||
a924c53e | 206 | // Get results for items of user 1 rated by user 3 |
d8c71388 EL |
207 | $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 3)); |
208 | $result = $rm->get_ratings($toptions); | |
209 | $this->assertEqual(count($result), count($user1posts)); | |
210 | $this->assertEqual($result[0]->id, $user1posts[0]->id); | |
211 | $this->assertEqual($result[0]->userid, $user1posts[0]->userid); | |
212 | $this->assertEqual($result[0]->message, $user1posts[0]->message); | |
213 | $this->assertEqual($result[0]->rating->count, 2); | |
214 | $this->assertEqual($result[0]->rating->aggregate, 2); | |
a924c53e | 215 | $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 1 "3" |
d8c71388 EL |
216 | $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid |
217 | ||
a924c53e | 218 | // Get results for items of user 1 & 2 together rated by user 3 |
d8c71388 EL |
219 | $posts = array_merge($user1posts, $user2posts); |
220 | $toptions = (object)array_merge($defaultoptions, array('items' => $posts, 'userid' => 3)); | |
221 | $result = $rm->get_ratings($toptions); | |
222 | $this->assertEqual(count($result), count($posts)); | |
223 | $this->assertEqual($result[0]->id, $posts[0]->id); | |
224 | $this->assertEqual($result[0]->userid, $posts[0]->userid); | |
225 | $this->assertEqual($result[0]->message, $posts[0]->message); | |
226 | $this->assertEqual($result[0]->rating->count, 2); | |
227 | $this->assertEqual($result[0]->rating->aggregate, 2); | |
a924c53e | 228 | $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 1 "3" |
d8c71388 EL |
229 | $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid |
230 | ||
231 | $this->assertEqual($result[1]->id, $posts[1]->id); | |
232 | $this->assertEqual($result[1]->userid, $posts[1]->userid); | |
233 | $this->assertEqual($result[1]->message, $posts[1]->message); | |
234 | $this->assertEqual($result[1]->rating->count, 2); | |
235 | $this->assertEqual($result[1]->rating->aggregate, 3); | |
a924c53e | 236 | $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 2 "5" |
d8c71388 EL |
237 | $this->assertEqual($result[1]->rating->userid, $toptions->userid); // Must be the passed userid |
238 | ||
a924c53e | 239 | // STEP 3: Some special cases |
d8c71388 | 240 | |
a924c53e AD |
241 | // Get results for user 1's items (expected average 1 + 3 / 2 = 2) |
242 | // supplying a non-existent user id so no rating from that user should be found | |
d8c71388 | 243 | $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts)); |
a924c53e | 244 | $toptions->userid = 123456; //non-existent user |
d8c71388 | 245 | $result = $rm->get_ratings($toptions); |
a924c53e AD |
246 | $this->assertNull($result[0]->rating->userid); |
247 | $this->assertNull($result[0]->rating->rating); | |
248 | $this->assertEqual($result[0]->rating->aggregate, 2);//should still get the aggregate | |
d8c71388 EL |
249 | |
250 | // Get results for items of user 2 (expected average 1 + 5 / 2 = 3) | |
a924c53e | 251 | // Supplying the user id of the user who owns the items so no rating should be found |
d8c71388 | 252 | $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts)); |
a924c53e | 253 | $toptions->userid = 2; //user 2 viewing the ratings of their own item |
d8c71388 | 254 | $result = $rm->get_ratings($toptions); |
a924c53e AD |
255 | //these should be null as the user is viewing their own item and thus cannot rate |
256 | $this->assertNull($result[0]->rating->userid); | |
257 | $this->assertNull($result[0]->rating->rating); | |
258 | $this->assertEqual($result[0]->rating->aggregate, 3);//should still get the aggregate | |
d8c71388 EL |
259 | } |
260 | } | |
e437d9f1 EL |
261 | |
262 | /** | |
263 | * rating_manager subclass for unit testing without requiring capabilities to be loaded | |
264 | */ | |
265 | class mockup_rating_manager extends rating_manager { | |
266 | ||
267 | /** | |
268 | * Overwrite get_plugin_permissions_array() so it always return granted perms for unit testing | |
269 | */ | |
270 | public function get_plugin_permissions_array($contextid, $component, $ratingarea) { | |
271 | return array( | |
272 | 'rate' => true, | |
273 | 'view' => true, | |
274 | 'viewany' => true, | |
275 | 'viewall' => true); | |
276 | } | |
277 | ||
278 | } |