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
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
29 require_once($CFG->dirroot . '/rating/lib.php');
32 * Unit test case for all the rating/lib.php requiring DB mockup & manipulation
34 class rating_db_test extends UnitTestCaseUsingDatabase {
36 public static $includecoverage = array(
40 protected $testtables = array(
44 public function setUp() {
47 $this->switch_to_test_db(); // Switch to test DB for all the execution
49 foreach ($this->testtables as $dir => $tables) {
50 $this->create_test_tables($tables, $dir); // Create tables
55 * Test the current get_ratings method main sql
57 function test_get_ratings_sql() {
59 // We load 3 items. Each is rated twice. For simplicity itemid == user id of the item owner
60 $ctxid = SYSCONTEXTID;
61 $this->load_test_data('rating',
62 array('contextid', 'component', 'ratingarea', 'itemid', 'scaleid', 'rating', 'userid', 'timecreated', 'timemodified'), array(
64 //user 1's items. Average == 2
65 array( $ctxid , 'mod_forum', 'post', 1 , 10 , 1 , 2 , 1 , 1),
66 array( $ctxid , 'mod_forum', 'post', 1 , 10 , 3 , 3 , 1 , 1),
68 //user 2's items. Average == 3
69 array( $ctxid , 'mod_forum', 'post', 2 , 10 , 1 , 1 , 1 , 1),
70 array( $ctxid , 'mod_forum', 'post', 2 , 10 , 5 , 3 , 1 , 1),
72 //user 3's items. Average == 4
73 array( $ctxid , 'mod_forum', 'post', 3 , 10 , 3 , 1 , 1 , 1),
74 array( $ctxid , 'mod_forum', 'post', 3 , 10 , 5 , 2 , 1 , 1)
77 // a post (item) by user 1 (rated above by user 2 and 3 with average = 2)
79 (object)array('id' => 1, 'userid' => 1, 'message' => 'hello'));
80 // a post (item) by user 2 (rated above by user 1 and 3 with average = 3)
82 (object)array('id' => 2, 'userid' => 2, 'message' => 'world'));
83 // a post (item) by user 3 (rated above by user 1 and 2 with average = 4)
85 (object)array('id' => 3, 'userid' => 3, 'message' => 'moodle'));
87 // Prepare the default options
88 $defaultoptions = array (
89 'context' => get_context_instance(CONTEXT_SYSTEM),
90 'component' => 'mod_forum',
91 'ratingarea' => 'post',
93 'aggregate' => RATING_AGGREGATE_AVERAGE);
95 $rm = new rating_manager();
97 // STEP 1: Retreive ratings using the current user
99 // Get results for user 1's item (expected average 1 + 3 / 2 = 2)
100 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts));
101 $result = $rm->get_ratings($toptions);
102 $this->assertEqual(count($result), count($user1posts));
103 $this->assertEqual($result[0]->id, $user1posts[0]->id);
104 $this->assertEqual($result[0]->userid, $user1posts[0]->userid);
105 $this->assertEqual($result[0]->message, $user1posts[0]->message);
106 $this->assertEqual($result[0]->rating->count, 2);
107 $this->assertEqual($result[0]->rating->aggregate, 2);
108 // Note that $result[0]->rating->rating is somewhat random
109 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
111 // Get results for items of user 2 (expected average 1 + 5 / 2 = 3)
112 $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts));
113 $result = $rm->get_ratings($toptions);
114 $this->assertEqual(count($result), count($user2posts));
115 $this->assertEqual($result[0]->id, $user2posts[0]->id);
116 $this->assertEqual($result[0]->userid, $user2posts[0]->userid);
117 $this->assertEqual($result[0]->message, $user2posts[0]->message);
118 $this->assertEqual($result[0]->rating->count, 2);
119 $this->assertEqual($result[0]->rating->aggregate, 3);
120 // Note that $result[0]->rating->rating is somewhat random
121 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
123 // Get results for items of user 3 (expected average 3 + 5 / 2 = 4)
124 $toptions = (object)array_merge($defaultoptions, array('items' => $user3posts));
125 $result = $rm->get_ratings($toptions);
126 $this->assertEqual(count($result), count($user3posts));
127 $this->assertEqual($result[0]->id, $user3posts[0]->id);
128 $this->assertEqual($result[0]->userid, $user3posts[0]->userid);
129 $this->assertEqual($result[0]->message, $user3posts[0]->message);
130 $this->assertEqual($result[0]->rating->count, 2);
131 $this->assertEqual($result[0]->rating->aggregate, 4);
132 // Note that $result[0]->rating->rating is somewhat random
133 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
135 // Get results for items of user 1 & 2 together (expected averages are 2 and 3, as tested above)
136 $posts = array_merge($user1posts, $user2posts);
137 $toptions = (object)array_merge($defaultoptions, array('items' => $posts));
138 $result = $rm->get_ratings($toptions);
139 $this->assertEqual(count($result), count($posts));
140 $this->assertEqual($result[0]->id, $posts[0]->id);
141 $this->assertEqual($result[0]->userid, $posts[0]->userid);
142 $this->assertEqual($result[0]->message, $posts[0]->message);
143 $this->assertEqual($result[0]->rating->count, 2);
144 $this->assertEqual($result[0]->rating->aggregate, 2);
145 // Note that $result[0]->rating->rating is somewhat random
146 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
148 $this->assertEqual($result[1]->id, $posts[1]->id);
149 $this->assertEqual($result[1]->userid, $posts[1]->userid);
150 $this->assertEqual($result[1]->message, $posts[1]->message);
151 $this->assertEqual($result[1]->rating->count, 2);
152 $this->assertEqual($result[1]->rating->aggregate, 3);
153 // Note that $result[0]->rating->rating is somewhat random
154 // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests
156 // STEP 2: Retrieve ratings by a specified user
157 // We still expect complete aggregations and counts
159 // Get results for items of user 1 rated by user 2 (avg 2, rating 1)
160 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 2));
161 $result = $rm->get_ratings($toptions);
162 $this->assertEqual(count($result), count($user1posts));
163 $this->assertEqual($result[0]->id, $user1posts[0]->id);
164 $this->assertEqual($result[0]->userid, $user1posts[0]->userid);
165 $this->assertEqual($result[0]->message, $user1posts[0]->message);
166 $this->assertEqual($result[0]->rating->count, 2);
167 $this->assertEqual($result[0]->rating->aggregate, 2);
168 $this->assertEqual($result[0]->rating->rating, 1); //user 2 rated user 1 "1"
169 $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid
171 // Get results for items of user 1 rated by user 3
172 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 3));
173 $result = $rm->get_ratings($toptions);
174 $this->assertEqual(count($result), count($user1posts));
175 $this->assertEqual($result[0]->id, $user1posts[0]->id);
176 $this->assertEqual($result[0]->userid, $user1posts[0]->userid);
177 $this->assertEqual($result[0]->message, $user1posts[0]->message);
178 $this->assertEqual($result[0]->rating->count, 2);
179 $this->assertEqual($result[0]->rating->aggregate, 2);
180 $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 1 "3"
181 $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid
183 // Get results for items of user 1 & 2 together rated by user 3
184 $posts = array_merge($user1posts, $user2posts);
185 $toptions = (object)array_merge($defaultoptions, array('items' => $posts, 'userid' => 3));
186 $result = $rm->get_ratings($toptions);
187 $this->assertEqual(count($result), count($posts));
188 $this->assertEqual($result[0]->id, $posts[0]->id);
189 $this->assertEqual($result[0]->userid, $posts[0]->userid);
190 $this->assertEqual($result[0]->message, $posts[0]->message);
191 $this->assertEqual($result[0]->rating->count, 2);
192 $this->assertEqual($result[0]->rating->aggregate, 2);
193 $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 1 "3"
194 $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid
196 $this->assertEqual($result[1]->id, $posts[1]->id);
197 $this->assertEqual($result[1]->userid, $posts[1]->userid);
198 $this->assertEqual($result[1]->message, $posts[1]->message);
199 $this->assertEqual($result[1]->rating->count, 2);
200 $this->assertEqual($result[1]->rating->aggregate, 3);
201 $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 2 "5"
202 $this->assertEqual($result[1]->rating->userid, $toptions->userid); // Must be the passed userid
204 // STEP 3: Some special cases
206 // Get results for user 1's items (expected average 1 + 3 / 2 = 2)
207 // supplying a non-existent user id so no rating from that user should be found
208 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts));
209 $toptions->userid = 123456; //non-existent user
210 $result = $rm->get_ratings($toptions);
211 $this->assertNull($result[0]->rating->userid);
212 $this->assertNull($result[0]->rating->rating);
213 $this->assertEqual($result[0]->rating->aggregate, 2);//should still get the aggregate
215 // Get results for items of user 2 (expected average 1 + 5 / 2 = 3)
216 // Supplying the user id of the user who owns the items so no rating should be found
217 $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts));
218 $toptions->userid = 2; //user 2 viewing the ratings of their own item
219 $result = $rm->get_ratings($toptions);
220 //these should be null as the user is viewing their own item and thus cannot rate
221 $this->assertNull($result[0]->rating->userid);
222 $this->assertNull($result[0]->rating->rating);
223 $this->assertEqual($result[0]->rating->aggregate, 3);//should still get the aggregate