Merge branch 'MDL-64284-36_get_component_classes_cache' of https://github.com/tomdick...
[moodle.git] / mod / glossary / tests / external_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 glossary functions unit tests
19  *
20  * @package    mod_glossary
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();
27 global $CFG;
28 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
30 /**
31  * External glossary functions unit tests
32  *
33  * @package    mod_glossary
34  * @category   external
35  * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class mod_glossary_external_testcase extends externallib_advanced_testcase {
40     /**
41      * Test get_glossaries_by_courses
42      */
43     public function test_get_glossaries_by_courses() {
44         $this->resetAfterTest(true);
46         // As admin.
47         $this->setAdminUser();
48         $c1 = self::getDataGenerator()->create_course();
49         $c2 = self::getDataGenerator()->create_course();
50         $g1 = self::getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'name' => 'First Glossary'));
51         $g2 = self::getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'name' => 'Second Glossary'));
52         $g3 = self::getDataGenerator()->create_module('glossary', array('course' => $c2->id, 'name' => 'Third Glossary'));
54         $s1 = $this->getDataGenerator()->create_user();
55         self::getDataGenerator()->enrol_user($s1->id,  $c1->id);
57         // Check results where student is enrolled.
58         $this->setUser($s1);
59         $glossaries = mod_glossary_external::get_glossaries_by_courses(array());
60         $glossaries = external_api::clean_returnvalue(mod_glossary_external::get_glossaries_by_courses_returns(), $glossaries);
62         $this->assertCount(2, $glossaries['glossaries']);
63         $this->assertEquals('First Glossary', $glossaries['glossaries'][0]['name']);
64         $this->assertEquals('Second Glossary', $glossaries['glossaries'][1]['name']);
65         $this->assertEquals(1, $glossaries['glossaries'][0]['canaddentry']);
66         $this->assertEquals(1, $glossaries['glossaries'][1]['canaddentry']);
68         // Check results with specific course IDs.
69         $glossaries = mod_glossary_external::get_glossaries_by_courses(array($c1->id, $c2->id));
70         $glossaries = external_api::clean_returnvalue(mod_glossary_external::get_glossaries_by_courses_returns(), $glossaries);
72         $this->assertCount(2, $glossaries['glossaries']);
73         $this->assertEquals('First Glossary', $glossaries['glossaries'][0]['name']);
74         $this->assertEquals('Second Glossary', $glossaries['glossaries'][1]['name']);
76         $this->assertEquals('course', $glossaries['warnings'][0]['item']);
77         $this->assertEquals($c2->id, $glossaries['warnings'][0]['itemid']);
78         $this->assertEquals('1', $glossaries['warnings'][0]['warningcode']);
79         $this->assertEquals(1, $glossaries['glossaries'][0]['canaddentry']);
81         // Now as admin.
82         $this->setAdminUser();
84         $glossaries = mod_glossary_external::get_glossaries_by_courses(array($c2->id));
85         $glossaries = external_api::clean_returnvalue(mod_glossary_external::get_glossaries_by_courses_returns(), $glossaries);
87         $this->assertCount(1, $glossaries['glossaries']);
88         $this->assertEquals('Third Glossary', $glossaries['glossaries'][0]['name']);
89         $this->assertEquals(1, $glossaries['glossaries'][0]['canaddentry']);
90     }
92     public function test_view_glossary() {
93         $this->resetAfterTest(true);
95         // Generate all the things.
96         $c1 = $this->getDataGenerator()->create_course();
97         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
98         $u1 = $this->getDataGenerator()->create_user();
99         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
101         $sink = $this->redirectEvents();
102         $this->setUser($u1);
103         $return = mod_glossary_external::view_glossary($g1->id, 'letter');
104         $return = external_api::clean_returnvalue(mod_glossary_external::view_glossary_returns(), $return);
105         $events = $sink->get_events();
107         // Assertion.
108         $this->assertTrue($return['status']);
109         $this->assertEmpty($return['warnings']);
110         $this->assertCount(1, $events);
111         $this->assertEquals('\mod_glossary\event\course_module_viewed', $events[0]->eventname);
112         $sink->close();
113     }
115     /**
116      * @expectedException        require_login_exception
117      * @expectedExceptionMessage Activity is hidden
118      */
119     public function test_view_glossary_without_permission() {
120         $this->resetAfterTest(true);
122         // Generate all the things.
123         $c1 = $this->getDataGenerator()->create_course();
124         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
125         $u1 = $this->getDataGenerator()->create_user();
126         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
127         $ctx = context_module::instance($g1->cmid);
129         // Revoke permission.
130         $roles = get_archetype_roles('user');
131         $role = array_shift($roles);
132         assign_capability('mod/glossary:view', CAP_PROHIBIT, $role->id, $ctx, true);
133         accesslib_clear_all_caches_for_unit_testing();
135         // Assertion.
136         $this->setUser($u1);
137         mod_glossary_external::view_glossary($g1->id, 'letter');
138     }
140     /**
141      * @expectedException        require_login_exception
142      * @expectedExceptionMessage Activity is hidden
143      */
144     public function test_view_entry() {
145         $this->resetAfterTest(true);
147         // Generate all the things.
148         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
149         $c1 = $this->getDataGenerator()->create_course();
150         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
151         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'visible' => false));
152         $u1 = $this->getDataGenerator()->create_user();
153         $e1 = $gg->create_content($g1, array('approved' => 1));
154         $e2 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u1->id));
155         $e3 = $gg->create_content($g1, array('approved' => 0, 'userid' => -1));
156         $e4 = $gg->create_content($g2, array('approved' => 1));
157         $ctx = context_module::instance($g1->cmid);
158         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
159         $this->setUser($u1);
161         // Test readable entry.
162         $sink = $this->redirectEvents();
163         $return = mod_glossary_external::view_entry($e1->id);
164         $return = external_api::clean_returnvalue(mod_glossary_external::view_entry_returns(), $return);
165         $events = $sink->get_events();
166         $this->assertTrue($return['status']);
167         $this->assertEmpty($return['warnings']);
168         $this->assertCount(1, $events);
169         $this->assertEquals('\mod_glossary\event\entry_viewed', $events[0]->eventname);
170         $sink->close();
172         // Test non-approved of self.
173         $return = mod_glossary_external::view_entry($e2->id);
174         $return = external_api::clean_returnvalue(mod_glossary_external::view_entry_returns(), $return);
175         $events = $sink->get_events();
176         $this->assertTrue($return['status']);
177         $this->assertEmpty($return['warnings']);
178         $this->assertCount(1, $events);
179         $this->assertEquals('\mod_glossary\event\entry_viewed', $events[0]->eventname);
180         $sink->close();
182         // Test non-approved of other.
183         try {
184             mod_glossary_external::view_entry($e3->id);
185             $this->fail('Cannot view non-approved entries of others.');
186         } catch (invalid_parameter_exception $e) {
187             // All good.
188         }
190         // Test non-readable entry.
191         mod_glossary_external::view_entry($e4->id);
192     }
194     public function test_get_entries_by_letter() {
195         $this->resetAfterTest(true);
197         // Generate all the things.
198         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
199         $c1 = $this->getDataGenerator()->create_course();
200         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
201         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
202         $u1 = $this->getDataGenerator()->create_user();
203         $ctx = context_module::instance($g1->cmid);
204         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
206         $e1a = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Bob', 'userid' => 2));
207         $e1b = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Jane', 'userid' => 2));
208         $e1c = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Alice', 'userid' => $u1->id));
209         $e1d = $gg->create_content($g1, array('approved' => 0, 'concept' => '0-day', 'userid' => $u1->id));
210         $e2a = $gg->create_content($g2);
212         $this->setAdminUser();
214         // Just a normal request from admin user.
215         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'ALL', 0, 20, array());
216         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
217         $this->assertCount(3, $return['entries']);
218         $this->assertEquals(3, $return['count']);
219         $this->assertEquals($e1c->id, $return['entries'][0]['id']);
220         $this->assertEquals($e1a->id, $return['entries'][1]['id']);
221         $this->assertEquals($e1b->id, $return['entries'][2]['id']);
223         // An admin user requesting all the entries.
224         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'ALL', 0, 20, array('includenotapproved' => 1));
225         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
226         $this->assertCount(4, $return['entries']);
227         $this->assertEquals(4, $return['count']);
228         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
229         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
230         $this->assertEquals($e1a->id, $return['entries'][2]['id']);
231         $this->assertEquals($e1b->id, $return['entries'][3]['id']);
233         // A normal user.
234         $this->setUser($u1);
235         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'ALL', 0, 20, array());
236         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
237         $this->assertCount(3, $return['entries']);
238         $this->assertEquals(3, $return['count']);
239         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
240         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
241         $this->assertEquals($e1b->id, $return['entries'][2]['id']);
243         // A normal user requesting to view all non approved entries.
244         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'ALL', 0, 20, array('includenotapproved' => 1));
245         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
246         $this->assertCount(3, $return['entries']);
247         $this->assertEquals(3, $return['count']);
248         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
249         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
250         $this->assertEquals($e1b->id, $return['entries'][2]['id']);
251     }
253     public function test_get_entries_by_letter_with_parameters() {
254         $this->resetAfterTest(true);
256         // Generate all the things.
257         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
258         $c1 = $this->getDataGenerator()->create_course();
259         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
260         $u1 = $this->getDataGenerator()->create_user();
261         $ctx = context_module::instance($g1->cmid);
262         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
264         $e1a = $gg->create_content($g1, array('approved' => 1, 'concept' => '0-day', 'userid' => $u1->id));
265         $e1b = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Bob', 'userid' => 2));
266         $e1c = $gg->create_content($g1, array('approved' => 1, 'concept' => '1-dayb', 'userid' => $u1->id));
268         $this->setUser($u1);
270         // Requesting a single letter.
271         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'b', 0, 20, array());
272         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
273         $this->assertCount(1, $return['entries']);
274         $this->assertEquals(1, $return['count']);
275         $this->assertEquals($e1b->id, $return['entries'][0]['id']);
277         // Requesting special letters.
278         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'SPECIAL', 0, 20, array());
279         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
280         $this->assertCount(2, $return['entries']);
281         $this->assertEquals(2, $return['count']);
282         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
283         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
285         // Requesting with limit.
286         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'ALL', 0, 1, array());
287         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
288         $this->assertCount(1, $return['entries']);
289         $this->assertEquals(3, $return['count']);
290         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
291         $return = mod_glossary_external::get_entries_by_letter($g1->id, 'ALL', 1, 2, array());
292         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_letter_returns(), $return);
293         $this->assertCount(2, $return['entries']);
294         $this->assertEquals(3, $return['count']);
295         $this->assertEquals($e1c->id, $return['entries'][0]['id']);
296         $this->assertEquals($e1b->id, $return['entries'][1]['id']);
297     }
299     public function test_get_entries_by_date() {
300         global $DB;
301         $this->resetAfterTest(true);
303         // Generate all the things.
304         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
305         $c1 = $this->getDataGenerator()->create_course();
306         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
307         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
308         $u1 = $this->getDataGenerator()->create_user();
309         $ctx = context_module::instance($g1->cmid);
310         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
312         $now = time();
313         $e1a = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Bob', 'userid' => $u1->id,
314             'timecreated' => 1, 'timemodified' => $now + 3600));
315         $e1b = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Jane', 'userid' => $u1->id,
316             'timecreated' => $now + 3600, 'timemodified' => 1));
317         $e1c = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Alice', 'userid' => $u1->id,
318             'timecreated' => $now + 1, 'timemodified' => $now + 1));
319         $e1d = $gg->create_content($g1, array('approved' => 0, 'concept' => '0-day', 'userid' => $u1->id,
320             'timecreated' => $now + 2, 'timemodified' => $now + 2));
321         $e2a = $gg->create_content($g2);
323         $this->setAdminUser($u1);
325         // Ordering by time modified descending.
326         $return = mod_glossary_external::get_entries_by_date($g1->id, 'UPDATE', 'DESC', 0, 20, array());
327         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
328         $this->assertCount(3, $return['entries']);
329         $this->assertEquals(3, $return['count']);
330         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
331         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
332         $this->assertEquals($e1b->id, $return['entries'][2]['id']);
334         // Ordering by time modified ascending.
335         $return = mod_glossary_external::get_entries_by_date($g1->id, 'UPDATE', 'ASC', 0, 20, array());
336         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
337         $this->assertCount(3, $return['entries']);
338         $this->assertEquals(3, $return['count']);
339         $this->assertEquals($e1b->id, $return['entries'][0]['id']);
340         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
341         $this->assertEquals($e1a->id, $return['entries'][2]['id']);
343         // Ordering by time created asc.
344         $return = mod_glossary_external::get_entries_by_date($g1->id, 'CREATION', 'ASC', 0, 20, array());
345         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
346         $this->assertCount(3, $return['entries']);
347         $this->assertEquals(3, $return['count']);
348         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
349         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
350         $this->assertEquals($e1b->id, $return['entries'][2]['id']);
352         // Ordering by time created descending.
353         $return = mod_glossary_external::get_entries_by_date($g1->id, 'CREATION', 'DESC', 0, 20, array());
354         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
355         $this->assertCount(3, $return['entries']);
356         $this->assertEquals(3, $return['count']);
357         $this->assertEquals($e1b->id, $return['entries'][0]['id']);
358         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
359         $this->assertEquals($e1a->id, $return['entries'][2]['id']);
361         // Ordering including to approve.
362         $return = mod_glossary_external::get_entries_by_date($g1->id, 'CREATION', 'ASC', 0, 20,
363             array('includenotapproved' => true));
364         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
365         $this->assertCount(4, $return['entries']);
366         $this->assertEquals(4, $return['count']);
367         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
368         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
369         $this->assertEquals($e1d->id, $return['entries'][2]['id']);
370         $this->assertEquals($e1b->id, $return['entries'][3]['id']);
372         // Ordering including to approve and pagination.
373         $return = mod_glossary_external::get_entries_by_date($g1->id, 'CREATION', 'ASC', 0, 2,
374             array('includenotapproved' => true));
375         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
376         $this->assertCount(2, $return['entries']);
377         $this->assertEquals(4, $return['count']);
378         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
379         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
380         $return = mod_glossary_external::get_entries_by_date($g1->id, 'CREATION', 'ASC', 2, 2,
381             array('includenotapproved' => true));
382         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_date_returns(), $return);
383         $this->assertCount(2, $return['entries']);
384         $this->assertEquals(4, $return['count']);
385         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
386         $this->assertEquals($e1b->id, $return['entries'][1]['id']);
387     }
389     public function test_get_categories() {
390         $this->resetAfterTest(true);
391         $this->setAdminUser();
393         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
394         $c1 = $this->getDataGenerator()->create_course();
395         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
396         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
397         $cat1a = $gg->create_category($g1);
398         $cat1b = $gg->create_category($g1);
399         $cat1c = $gg->create_category($g1);
400         $cat2a = $gg->create_category($g2);
402         $return = mod_glossary_external::get_categories($g1->id, 0, 20);
403         $return = external_api::clean_returnvalue(mod_glossary_external::get_categories_returns(), $return);
404         $this->assertCount(3, $return['categories']);
405         $this->assertEquals(3, $return['count']);
406         $this->assertEquals($cat1a->id, $return['categories'][0]['id']);
407         $this->assertEquals($cat1b->id, $return['categories'][1]['id']);
408         $this->assertEquals($cat1c->id, $return['categories'][2]['id']);
410         $return = mod_glossary_external::get_categories($g1->id, 1, 2);
411         $return = external_api::clean_returnvalue(mod_glossary_external::get_categories_returns(), $return);
412         $this->assertCount(2, $return['categories']);
413         $this->assertEquals(3, $return['count']);
414         $this->assertEquals($cat1b->id, $return['categories'][0]['id']);
415         $this->assertEquals($cat1c->id, $return['categories'][1]['id']);
416     }
418     public function test_get_entries_by_category() {
419         $this->resetAfterTest(true);
421         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
422         $c1 = $this->getDataGenerator()->create_course();
423         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
424         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
425         $u1 = $this->getDataGenerator()->create_user();
426         $ctx = context_module::instance($g1->cmid);
428         $e1a1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
429         $e1a2 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
430         $e1a3 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
431         $e1b1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
432         $e1b2 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u1->id));
433         $e1x1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
434         $e1x2 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u1->id));
435         $e2a1 = $gg->create_content($g2, array('approved' => 1, 'userid' => $u1->id));
436         $e2a2 = $gg->create_content($g2, array('approved' => 1, 'userid' => $u1->id));
438         $cat1a = $gg->create_category($g1, array('name' => 'Fish'), array($e1a1, $e1a2, $e1a3));
439         $cat1b = $gg->create_category($g1, array('name' => 'Cat'), array($e1b1, $e1b2));
440         $cat1c = $gg->create_category($g1, array('name' => 'Zebra'), array($e1b1));   // Entry $e1b1 is in two categories.
441         $cat2a = $gg->create_category($g2, array(), array($e2a1, $e2a2));
443         $this->setAdminUser();
445         // Browse one category.
446         $return = mod_glossary_external::get_entries_by_category($g1->id, $cat1a->id, 0, 20, array());
447         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_category_returns(), $return);
448         $this->assertCount(3, $return['entries']);
449         $this->assertEquals(3, $return['count']);
450         $this->assertEquals($e1a1->id, $return['entries'][0]['id']);
451         $this->assertEquals($e1a2->id, $return['entries'][1]['id']);
452         $this->assertEquals($e1a3->id, $return['entries'][2]['id']);
454         // Browse all categories.
455         $return = mod_glossary_external::get_entries_by_category($g1->id, GLOSSARY_SHOW_ALL_CATEGORIES, 0, 20, array());
456         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_category_returns(), $return);
457         $this->assertCount(5, $return['entries']);
458         $this->assertEquals(5, $return['count']);
459         $this->assertEquals($e1b1->id, $return['entries'][0]['id']);
460         $this->assertEquals($e1a1->id, $return['entries'][1]['id']);
461         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
462         $this->assertEquals($e1a3->id, $return['entries'][3]['id']);
463         $this->assertEquals($e1b1->id, $return['entries'][4]['id']);
465         // Browse uncategorised.
466         $return = mod_glossary_external::get_entries_by_category($g1->id, GLOSSARY_SHOW_NOT_CATEGORISED, 0, 20, array());
467         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_category_returns(), $return);
468         $this->assertCount(1, $return['entries']);
469         $this->assertEquals(1, $return['count']);
470         $this->assertEquals($e1x1->id, $return['entries'][0]['id']);
472         // Including to approve.
473         $return = mod_glossary_external::get_entries_by_category($g1->id, $cat1b->id, 0, 20,
474             array('includenotapproved' => true));
475         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_category_returns(), $return);
476         $this->assertCount(2, $return['entries']);
477         $this->assertEquals(2, $return['count']);
478         $this->assertEquals($e1b1->id, $return['entries'][0]['id']);
479         $this->assertEquals($e1b2->id, $return['entries'][1]['id']);
481         // Using limit.
482         $return = mod_glossary_external::get_entries_by_category($g1->id, GLOSSARY_SHOW_ALL_CATEGORIES, 0, 3,
483             array('includenotapproved' => true));
484         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_category_returns(), $return);
485         $this->assertCount(3, $return['entries']);
486         $this->assertEquals(6, $return['count']);
487         $this->assertEquals($e1b1->id, $return['entries'][0]['id']);
488         $this->assertEquals($e1b2->id, $return['entries'][1]['id']);
489         $this->assertEquals($e1a1->id, $return['entries'][2]['id']);
490         $return = mod_glossary_external::get_entries_by_category($g1->id, GLOSSARY_SHOW_ALL_CATEGORIES, 3, 2,
491             array('includenotapproved' => true));
492         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_category_returns(), $return);
493         $this->assertCount(2, $return['entries']);
494         $this->assertEquals(6, $return['count']);
495         $this->assertEquals($e1a2->id, $return['entries'][0]['id']);
496         $this->assertEquals($e1a3->id, $return['entries'][1]['id']);
497     }
499     public function test_get_authors() {
500         $this->resetAfterTest(true);
502         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
503         $c1 = $this->getDataGenerator()->create_course();
504         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
505         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
507         $u1 = $this->getDataGenerator()->create_user(array('lastname' => 'Upsilon'));
508         $u2 = $this->getDataGenerator()->create_user(array('lastname' => 'Alpha'));
509         $u3 = $this->getDataGenerator()->create_user(array('lastname' => 'Omega'));
511         $ctx = context_module::instance($g1->cmid);
513         $e1a = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1));
514         $e1b = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1));
515         $e1c = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1));
516         $e2a = $gg->create_content($g1, array('userid' => $u2->id, 'approved' => 1));
517         $e3a = $gg->create_content($g1, array('userid' => $u3->id, 'approved' => 0));
519         $this->setAdminUser();
521         // Simple request.
522         $return = mod_glossary_external::get_authors($g1->id, 0, 20, array());
523         $return = external_api::clean_returnvalue(mod_glossary_external::get_authors_returns(), $return);
524         $this->assertCount(2, $return['authors']);
525         $this->assertEquals(2, $return['count']);
526         $this->assertEquals($u2->id, $return['authors'][0]['id']);
527         $this->assertEquals($u1->id, $return['authors'][1]['id']);
529         // Include users with entries pending approval.
530         $return = mod_glossary_external::get_authors($g1->id, 0, 20, array('includenotapproved' => true));
531         $return = external_api::clean_returnvalue(mod_glossary_external::get_authors_returns(), $return);
532         $this->assertCount(3, $return['authors']);
533         $this->assertEquals(3, $return['count']);
534         $this->assertEquals($u2->id, $return['authors'][0]['id']);
535         $this->assertEquals($u3->id, $return['authors'][1]['id']);
536         $this->assertEquals($u1->id, $return['authors'][2]['id']);
538         // Pagination.
539         $return = mod_glossary_external::get_authors($g1->id, 1, 1, array('includenotapproved' => true));
540         $return = external_api::clean_returnvalue(mod_glossary_external::get_authors_returns(), $return);
541         $this->assertCount(1, $return['authors']);
542         $this->assertEquals(3, $return['count']);
543         $this->assertEquals($u3->id, $return['authors'][0]['id']);
544     }
546     public function test_get_entries_by_author() {
547         $this->resetAfterTest(true);
549         // Generate all the things.
550         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
551         $c1 = $this->getDataGenerator()->create_course();
552         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
553         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
554         $u1 = $this->getDataGenerator()->create_user(array('lastname' => 'Upsilon', 'firstname' => 'Zac'));
555         $u2 = $this->getDataGenerator()->create_user(array('lastname' => 'Ultra', 'firstname' => '1337'));
556         $u3 = $this->getDataGenerator()->create_user(array('lastname' => 'Alpha', 'firstname' => 'Omega'));
557         $u4 = $this->getDataGenerator()->create_user(array('lastname' => '0-day', 'firstname' => 'Zoe'));
558         $ctx = context_module::instance($g1->cmid);
559         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
561         $e1a1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
562         $e1a2 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
563         $e1a3 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
564         $e1b1 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u2->id));
565         $e1b2 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u2->id));
566         $e1c1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u3->id));
567         $e1d1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u4->id));
568         $e2a = $gg->create_content($g2, array('approved' => 1, 'userid' => $u1->id));
570         $this->setUser($u1);
572         // Requesting a single letter.
573         $return = mod_glossary_external::get_entries_by_author($g1->id, 'u', 'LASTNAME', 'ASC', 0, 20, array());
574         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
575         $this->assertCount(4, $return['entries']);
576         $this->assertEquals(4, $return['count']);
577         $this->assertEquals($e1b2->id, $return['entries'][0]['id']);
578         $this->assertEquals($e1a1->id, $return['entries'][1]['id']);
579         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
580         $this->assertEquals($e1a3->id, $return['entries'][3]['id']);
582         // Requesting special letters.
583         $return = mod_glossary_external::get_entries_by_author($g1->id, 'SPECIAL', 'LASTNAME', 'ASC', 0, 20, array());
584         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
585         $this->assertCount(1, $return['entries']);
586         $this->assertEquals(1, $return['count']);
587         $this->assertEquals($e1d1->id, $return['entries'][0]['id']);
589         // Requesting with limit.
590         $return = mod_glossary_external::get_entries_by_author($g1->id, 'ALL', 'LASTNAME', 'ASC', 0, 1, array());
591         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
592         $this->assertCount(1, $return['entries']);
593         $this->assertEquals(6, $return['count']);
594         $this->assertEquals($e1d1->id, $return['entries'][0]['id']);
595         $return = mod_glossary_external::get_entries_by_author($g1->id, 'ALL', 'LASTNAME', 'ASC', 1, 2, array());
596         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
597         $this->assertCount(2, $return['entries']);
598         $this->assertEquals(6, $return['count']);
599         $this->assertEquals($e1c1->id, $return['entries'][0]['id']);
600         $this->assertEquals($e1b2->id, $return['entries'][1]['id']);
602         // Including non-approved.
603         $this->setAdminUser();
604         $return = mod_glossary_external::get_entries_by_author($g1->id, 'ALL', 'LASTNAME', 'ASC', 0, 20,
605             array('includenotapproved' => true));
606         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
607         $this->assertCount(7, $return['entries']);
608         $this->assertEquals(7, $return['count']);
609         $this->assertEquals($e1d1->id, $return['entries'][0]['id']);
610         $this->assertEquals($e1c1->id, $return['entries'][1]['id']);
611         $this->assertEquals($e1b1->id, $return['entries'][2]['id']);
612         $this->assertEquals($e1b2->id, $return['entries'][3]['id']);
613         $this->assertEquals($e1a1->id, $return['entries'][4]['id']);
614         $this->assertEquals($e1a2->id, $return['entries'][5]['id']);
615         $this->assertEquals($e1a3->id, $return['entries'][6]['id']);
617         // Changing order.
618         $return = mod_glossary_external::get_entries_by_author($g1->id, 'ALL', 'LASTNAME', 'DESC', 0, 1, array());
619         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
620         $this->assertCount(1, $return['entries']);
621         $this->assertEquals(6, $return['count']);
622         $this->assertEquals($e1a1->id, $return['entries'][0]['id']);
624         // Sorting by firstname.
625         $return = mod_glossary_external::get_entries_by_author($g1->id, 'ALL', 'FIRSTNAME', 'ASC', 0, 1, array());
626         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
627         $this->assertCount(1, $return['entries']);
628         $this->assertEquals(6, $return['count']);
629         $this->assertEquals($e1b2->id, $return['entries'][0]['id']);
631         // Sorting by firstname descending.
632         $return = mod_glossary_external::get_entries_by_author($g1->id, 'ALL', 'FIRSTNAME', 'DESC', 0, 1, array());
633         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
634         $this->assertCount(1, $return['entries']);
635         $this->assertEquals(6, $return['count']);
636         $this->assertEquals($e1d1->id, $return['entries'][0]['id']);
638         // Filtering by firstname descending.
639         $return = mod_glossary_external::get_entries_by_author($g1->id, 'z', 'FIRSTNAME', 'DESC', 0, 20, array());
640         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
641         $this->assertCount(4, $return['entries']);
642         $this->assertEquals(4, $return['count']);
643         $this->assertEquals($e1d1->id, $return['entries'][0]['id']);
644         $this->assertEquals($e1a1->id, $return['entries'][1]['id']);
645         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
646         $this->assertEquals($e1a3->id, $return['entries'][3]['id']);
648         // Test with a deleted user.
649         delete_user($u2);
650         $return = mod_glossary_external::get_entries_by_author($g1->id, 'u', 'LASTNAME', 'ASC', 0, 20, array());
651         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_returns(), $return);
652         $this->assertCount(4, $return['entries']);
653         $this->assertEquals(4, $return['count']);
654         $this->assertEquals($e1b2->id, $return['entries'][0]['id']);
655         $this->assertEquals($e1a1->id, $return['entries'][1]['id']);
656         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
657         $this->assertEquals($e1a3->id, $return['entries'][3]['id']);
658     }
660     public function test_get_entries_by_author_id() {
661         $this->resetAfterTest(true);
663         // Generate all the things.
664         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
665         $c1 = $this->getDataGenerator()->create_course();
666         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
667         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'displayformat' => 'entrylist'));
668         $u1 = $this->getDataGenerator()->create_user(array('lastname' => 'Upsilon', 'firstname' => 'Zac'));
669         $u2 = $this->getDataGenerator()->create_user(array('lastname' => 'Ultra', 'firstname' => '1337'));
670         $u3 = $this->getDataGenerator()->create_user(array('lastname' => 'Alpha', 'firstname' => 'Omega'));
671         $u4 = $this->getDataGenerator()->create_user(array('lastname' => '0-day', 'firstname' => 'Zoe'));
672         $ctx = context_module::instance($g1->cmid);
673         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
675         $e1a1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id, 'concept' => 'Zoom',
676             'timecreated' => 3600, 'timemodified' => time() - 3600));
677         $e1a2 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id, 'concept' => 'Alpha'));
678         $e1a3 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id, 'concept' => 'Dog',
679             'timecreated' => 1, 'timemodified' => time() - 1800));
680         $e1a4 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u1->id, 'concept' => 'Bird'));
681         $e1b1 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u2->id));
682         $e2a = $gg->create_content($g2, array('approved' => 1, 'userid' => $u1->id));
684         $this->setAdminUser();
686         // Standard request.
687         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CONCEPT', 'ASC', 0, 20, array());
688         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
689         $this->assertCount(3, $return['entries']);
690         $this->assertEquals(3, $return['count']);
691         $this->assertEquals($e1a2->id, $return['entries'][0]['id']);
692         $this->assertEquals($e1a3->id, $return['entries'][1]['id']);
693         $this->assertEquals($e1a1->id, $return['entries'][2]['id']);
695         // Standard request descending.
696         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CONCEPT', 'DESC', 0, 20, array());
697         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
698         $this->assertCount(3, $return['entries']);
699         $this->assertEquals(3, $return['count']);
700         $this->assertEquals($e1a1->id, $return['entries'][0]['id']);
701         $this->assertEquals($e1a3->id, $return['entries'][1]['id']);
702         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
704         // Requesting ordering by time created.
705         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CREATION', 'ASC', 0, 20, array());
706         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
707         $this->assertCount(3, $return['entries']);
708         $this->assertEquals(3, $return['count']);
709         $this->assertEquals($e1a3->id, $return['entries'][0]['id']);
710         $this->assertEquals($e1a1->id, $return['entries'][1]['id']);
711         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
713         // Requesting ordering by time created descending.
714         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CREATION', 'DESC', 0, 20, array());
715         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
716         $this->assertCount(3, $return['entries']);
717         $this->assertEquals(3, $return['count']);
718         $this->assertEquals($e1a2->id, $return['entries'][0]['id']);
719         $this->assertEquals($e1a1->id, $return['entries'][1]['id']);
720         $this->assertEquals($e1a3->id, $return['entries'][2]['id']);
722         // Requesting ordering by time modified.
723         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'UPDATE', 'ASC', 0, 20, array());
724         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
725         $this->assertCount(3, $return['entries']);
726         $this->assertEquals(3, $return['count']);
727         $this->assertEquals($e1a1->id, $return['entries'][0]['id']);
728         $this->assertEquals($e1a3->id, $return['entries'][1]['id']);
729         $this->assertEquals($e1a2->id, $return['entries'][2]['id']);
731         // Requesting ordering by time modified descending.
732         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'UPDATE', 'DESC', 0, 20, array());
733         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
734         $this->assertCount(3, $return['entries']);
735         $this->assertEquals(3, $return['count']);
736         $this->assertEquals($e1a2->id, $return['entries'][0]['id']);
737         $this->assertEquals($e1a3->id, $return['entries'][1]['id']);
738         $this->assertEquals($e1a1->id, $return['entries'][2]['id']);
740         // Including non approved.
741         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CONCEPT', 'ASC', 0, 20,
742             array('includenotapproved' => true));
743         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
744         $this->assertCount(4, $return['entries']);
745         $this->assertEquals(4, $return['count']);
746         $this->assertEquals($e1a2->id, $return['entries'][0]['id']);
747         $this->assertEquals($e1a4->id, $return['entries'][1]['id']);
748         $this->assertEquals($e1a3->id, $return['entries'][2]['id']);
749         $this->assertEquals($e1a1->id, $return['entries'][3]['id']);
751         // Pagination.
752         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CONCEPT', 'ASC', 0, 2,
753             array('includenotapproved' => true));
754         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
755         $this->assertCount(2, $return['entries']);
756         $this->assertEquals(4, $return['count']);
757         $this->assertEquals($e1a2->id, $return['entries'][0]['id']);
758         $this->assertEquals($e1a4->id, $return['entries'][1]['id']);
759         $return = mod_glossary_external::get_entries_by_author_id($g1->id, $u1->id, 'CONCEPT', 'ASC', 1, 2,
760             array('includenotapproved' => true));
761         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_author_id_returns(), $return);
762         $this->assertCount(2, $return['entries']);
763         $this->assertEquals(4, $return['count']);
764         $this->assertEquals($e1a4->id, $return['entries'][0]['id']);
765         $this->assertEquals($e1a3->id, $return['entries'][1]['id']);
766     }
768     public function test_get_entries_by_search() {
769         $this->resetAfterTest(true);
771         // Generate all the things.
772         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
773         $c1 = $this->getDataGenerator()->create_course();
774         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
775         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
776         $u1 = $this->getDataGenerator()->create_user();
777         $ctx = context_module::instance($g1->cmid);
778         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
779         $this->setUser($u1);
781         $e1 = $gg->create_content($g1, array('approved' => 1, 'concept' => 'House', 'timecreated' => time() + 3600));
782         $e2 = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Mouse', 'timemodified' => 1));
783         $e3 = $gg->create_content($g1, array('approved' => 1, 'concept' => 'Hero'));
784         $e4 = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Toulouse'));
785         $e5 = $gg->create_content($g1, array('approved' => 1, 'definition' => 'Heroes', 'concept' => 'Abcd'));
786         $e6 = $gg->create_content($g1, array('approved' => 0, 'definition' => 'When used for Heroes'));
787         $e7 = $gg->create_content($g1, array('approved' => 1, 'timecreated' => 1, 'timemodified' => time() + 3600,
788             'concept' => 'Z'), array('Couscous'));
789         $e8 = $gg->create_content($g1, array('approved' => 0), array('Heroes'));
790         $e9 = $gg->create_content($g2, array('approved' => 0));
792         $this->setAdminUser();
794         // Test simple query.
795         $query = 'hero';
796         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'CONCEPT', 'ASC', 0, 20, array());
797         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
798         $this->assertCount(1, $return['entries']);
799         $this->assertEquals(1, $return['count']);
800         $this->assertEquals($e3->id, $return['entries'][0]['id']);
802         // Enabling full search.
803         $query = 'hero';
804         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, true, 'CONCEPT', 'ASC', 0, 20, array());
805         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
806         $this->assertCount(2, $return['entries']);
807         $this->assertEquals(2, $return['count']);
808         $this->assertEquals($e5->id, $return['entries'][0]['id']);
809         $this->assertEquals($e3->id, $return['entries'][1]['id']);
811         // Concept descending.
812         $query = 'hero';
813         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, true, 'CONCEPT', 'DESC', 0, 20, array());
814         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
815         $this->assertCount(2, $return['entries']);
816         $this->assertEquals(2, $return['count']);
817         $this->assertEquals($e3->id, $return['entries'][0]['id']);
818         $this->assertEquals($e5->id, $return['entries'][1]['id']);
820         // Search on alias.
821         $query = 'couscous';
822         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'CONCEPT', 'ASC', 0, 20, array());
823         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
824         $this->assertCount(1, $return['entries']);
825         $this->assertEquals(1, $return['count']);
826         $this->assertEquals($e7->id, $return['entries'][0]['id']);
827         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, true, 'CONCEPT', 'ASC', 0, 20, array());
828         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
829         $this->assertCount(1, $return['entries']);
830         $this->assertEquals(1, $return['count']);
831         $this->assertEquals($e7->id, $return['entries'][0]['id']);
833         // Pagination and ordering on created date.
834         $query = 'ou';
835         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'CREATION', 'ASC', 0, 1, array());
836         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
837         $this->assertCount(1, $return['entries']);
838         $this->assertEquals(3, $return['count']);
839         $this->assertEquals($e7->id, $return['entries'][0]['id']);
840         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'CREATION', 'DESC', 0, 1, array());
841         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
842         $this->assertCount(1, $return['entries']);
843         $this->assertEquals(3, $return['count']);
844         $this->assertEquals($e1->id, $return['entries'][0]['id']);
846         // Ordering on updated date.
847         $query = 'ou';
848         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'UPDATE', 'ASC', 0, 1, array());
849         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
850         $this->assertCount(1, $return['entries']);
851         $this->assertEquals(3, $return['count']);
852         $this->assertEquals($e2->id, $return['entries'][0]['id']);
853         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'UPDATE', 'DESC', 0, 1, array());
854         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
855         $this->assertCount(1, $return['entries']);
856         $this->assertEquals(3, $return['count']);
857         $this->assertEquals($e7->id, $return['entries'][0]['id']);
859         // Including not approved.
860         $query = 'ou';
861         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, false, 'CONCEPT', 'ASC', 0, 20,
862             array('includenotapproved' => true));
863         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
864         $this->assertCount(4, $return['entries']);
865         $this->assertEquals(4, $return['count']);
866         $this->assertEquals($e1->id, $return['entries'][0]['id']);
867         $this->assertEquals($e2->id, $return['entries'][1]['id']);
868         $this->assertEquals($e4->id, $return['entries'][2]['id']);
869         $this->assertEquals($e7->id, $return['entries'][3]['id']);
871         // Advanced query string.
872         $query = '+Heroes -Abcd';
873         $return = mod_glossary_external::get_entries_by_search($g1->id, $query, true, 'CONCEPT', 'ASC', 0, 20,
874             array('includenotapproved' => true));
875         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_search_returns(), $return);
876         $this->assertCount(2, $return['entries']);
877         $this->assertEquals(2, $return['count']);
878         $this->assertEquals($e6->id, $return['entries'][0]['id']);
879         $this->assertEquals($e8->id, $return['entries'][1]['id']);
880     }
882     public function test_get_entries_by_term() {
883         $this->resetAfterTest(true);
885         // Generate all the things.
886         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
887         $c1 = $this->getDataGenerator()->create_course();
888         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
889         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
890         $u1 = $this->getDataGenerator()->create_user();
891         $ctx = context_module::instance($g1->cmid);
892         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
894         $this->setAdminUser();
896         $e1 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1, 'concept' => 'cat'));
897         $e2 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1), array('cat', 'dog'));
898         $e3 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 1), array('dog'));
899         $e4 = $gg->create_content($g1, array('userid' => $u1->id, 'approved' => 0, 'concept' => 'dog'));
900         $e5 = $gg->create_content($g2, array('userid' => $u1->id, 'approved' => 1, 'concept' => 'dog'), array('cat'));
902         // Search concept + alias.
903         $return = mod_glossary_external::get_entries_by_term($g1->id, 'cat', 0, 20, array('includenotapproved' => false));
904         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
905         $this->assertCount(2, $return['entries']);
906         $this->assertEquals(2, $return['count']);
907         // Compare ids, ignore ordering of array, using canonicalize parameter of assertEquals.
908         $expected = array($e1->id, $e2->id);
909         $actual = array($return['entries'][0]['id'], $return['entries'][1]['id']);
910         $this->assertEquals($expected, $actual, '', 0.0, 10, true);
912         // Search alias.
913         $return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 0, 20, array('includenotapproved' => false));
914         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
916         $this->assertCount(2, $return['entries']);
917         $this->assertEquals(2, $return['count']);
918         // Compare ids, ignore ordering of array, using canonicalize parameter of assertEquals.
919         $expected = array($e2->id, $e3->id);
920         $actual = array($return['entries'][0]['id'], $return['entries'][1]['id']);
921         $this->assertEquals($expected, $actual, '', 0.0, 10, true);
923         // Search including not approved.
924         $return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 0, 20, array('includenotapproved' => true));
925         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
926         $this->assertCount(3, $return['entries']);
927         $this->assertEquals(3, $return['count']);
928         // Compare ids, ignore ordering of array, using canonicalize parameter of assertEquals.
929         $expected = array($e4->id, $e2->id, $e3->id);
930         $actual = array($return['entries'][0]['id'], $return['entries'][1]['id'], $return['entries'][2]['id']);
931         $this->assertEquals($expected, $actual, '', 0.0, 10, true);
933         // Pagination.
934         $return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 0, 1, array('includenotapproved' => true));
935         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
936         $this->assertCount(1, $return['entries']);
937         // We don't compare the returned entry id because it may be different depending on the DBMS,
938         // for example, Postgres does a random sorting in this case.
939         $this->assertEquals(3, $return['count']);
940         $return = mod_glossary_external::get_entries_by_term($g1->id, 'dog', 1, 1, array('includenotapproved' => true));
941         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_by_term_returns(), $return);
942         $this->assertCount(1, $return['entries']);
943         $this->assertEquals(3, $return['count']);
944     }
946     public function test_get_entries_to_approve() {
947         $this->resetAfterTest(true);
949         // Generate all the things.
950         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
951         $c1 = $this->getDataGenerator()->create_course();
952         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
953         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
954         $u1 = $this->getDataGenerator()->create_user();
955         $ctx = context_module::instance($g1->cmid);
956         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
958         $e1a = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Bob', 'userid' => $u1->id,
959             'timecreated' => time() + 3600));
960         $e1b = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Jane', 'userid' => $u1->id, 'timecreated' => 1));
961         $e1c = $gg->create_content($g1, array('approved' => 0, 'concept' => 'Alice', 'userid' => $u1->id, 'timemodified' => 1));
962         $e1d = $gg->create_content($g1, array('approved' => 0, 'concept' => '0-day', 'userid' => $u1->id,
963             'timemodified' => time() + 3600));
964         $e1e = $gg->create_content($g1, array('approved' => 1, 'concept' => '1-day', 'userid' => $u1->id));
965         $e2a = $gg->create_content($g2);
967         $this->setAdminUser(true);
969         // Simple listing.
970         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 0, 20);
971         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
972         $this->assertCount(4, $return['entries']);
973         $this->assertEquals(4, $return['count']);
974         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
975         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
976         $this->assertEquals($e1a->id, $return['entries'][2]['id']);
977         $this->assertEquals($e1b->id, $return['entries'][3]['id']);
979         // Revert ordering of concept.
980         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'DESC', 0, 20);
981         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
982         $this->assertCount(4, $return['entries']);
983         $this->assertEquals(4, $return['count']);
984         $this->assertEquals($e1b->id, $return['entries'][0]['id']);
985         $this->assertEquals($e1a->id, $return['entries'][1]['id']);
986         $this->assertEquals($e1c->id, $return['entries'][2]['id']);
987         $this->assertEquals($e1d->id, $return['entries'][3]['id']);
989         // Filtering by letter.
990         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'a', 'CONCEPT', 'ASC', 0, 20);
991         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
992         $this->assertCount(1, $return['entries']);
993         $this->assertEquals(1, $return['count']);
994         $this->assertEquals($e1c->id, $return['entries'][0]['id']);
996         // Filtering by special.
997         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'SPECIAL', 'CONCEPT', 'ASC', 0, 20);
998         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
999         $this->assertCount(1, $return['entries']);
1000         $this->assertEquals(1, $return['count']);
1001         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
1003         // Pagination.
1004         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 0, 2);
1005         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
1006         $this->assertCount(2, $return['entries']);
1007         $this->assertEquals(4, $return['count']);
1008         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
1009         $this->assertEquals($e1c->id, $return['entries'][1]['id']);
1010         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 1, 2);
1011         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
1012         $this->assertCount(2, $return['entries']);
1013         $this->assertEquals(4, $return['count']);
1014         $this->assertEquals($e1c->id, $return['entries'][0]['id']);
1015         $this->assertEquals($e1a->id, $return['entries'][1]['id']);
1017         // Ordering by creation date.
1018         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CREATION', 'ASC', 0, 1);
1019         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
1020         $this->assertCount(1, $return['entries']);
1021         $this->assertEquals(4, $return['count']);
1022         $this->assertEquals($e1b->id, $return['entries'][0]['id']);
1024         // Ordering by creation date desc.
1025         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CREATION', 'DESC', 0, 1);
1026         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
1027         $this->assertCount(1, $return['entries']);
1028         $this->assertEquals(4, $return['count']);
1029         $this->assertEquals($e1a->id, $return['entries'][0]['id']);
1031         // Ordering by update date.
1032         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'UPDATE', 'ASC', 0, 1);
1033         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
1034         $this->assertCount(1, $return['entries']);
1035         $this->assertEquals(4, $return['count']);
1036         $this->assertEquals($e1c->id, $return['entries'][0]['id']);
1038         // Ordering by update date desc.
1039         $return = mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'UPDATE', 'DESC', 0, 1);
1040         $return = external_api::clean_returnvalue(mod_glossary_external::get_entries_to_approve_returns(), $return);
1041         $this->assertCount(1, $return['entries']);
1042         $this->assertEquals(4, $return['count']);
1043         $this->assertEquals($e1d->id, $return['entries'][0]['id']);
1045         // Permissions are checked.
1046         $this->setUser($u1);
1047         $this->expectException('required_capability_exception');
1048         mod_glossary_external::get_entries_to_approve($g1->id, 'ALL', 'CONCEPT', 'ASC', 0, 1);
1049         $this->fail('Do not test anything else after this.');
1050     }
1052     public function test_get_entry_by_id() {
1053         $this->resetAfterTest(true);
1055         // Generate all the things.
1056         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
1057         $c1 = $this->getDataGenerator()->create_course();
1058         $c2 = $this->getDataGenerator()->create_course();
1059         $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
1060         $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'visible' => 0));
1061         $u1 = $this->getDataGenerator()->create_user();
1062         $u2 = $this->getDataGenerator()->create_user();
1063         $ctx = context_module::instance($g1->cmid);
1064         $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
1066         $e1 = $gg->create_content($g1, array('approved' => 1, 'userid' => $u1->id));
1067         // Add a fake inline image to the entry.
1068         $filename = 'shouldbeanimage.jpg';
1069         $filerecordinline = array(
1070             'contextid' => $ctx->id,
1071             'component' => 'mod_glossary',
1072             'filearea'  => 'entry',
1073             'itemid'    => $e1->id,
1074             'filepath'  => '/',
1075             'filename'  => $filename,
1076         );
1077         $fs = get_file_storage();
1078         $fs->create_file_from_string($filerecordinline, 'image contents (not really)');
1080         $e2 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u1->id));
1081         $e3 = $gg->create_content($g1, array('approved' => 0, 'userid' => $u2->id));
1082         $e4 = $gg->create_content($g2, array('approved' => 1));
1084         $this->setUser($u1);
1085         $return = mod_glossary_external::get_entry_by_id($e1->id);
1086         $return = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $return);
1087         $this->assertEquals($e1->id, $return['entry']['id']);
1088         $this->assertEquals($filename, $return['entry']['definitioninlinefiles'][0]['filename']);
1090         $return = mod_glossary_external::get_entry_by_id($e2->id);
1091         $return = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $return);
1092         $this->assertEquals($e2->id, $return['entry']['id']);
1094         try {
1095             $return = mod_glossary_external::get_entry_by_id($e3->id);
1096             $this->fail('Cannot view unapproved entries of others.');
1097         } catch (invalid_parameter_exception $e) {
1098             // All good.
1099         }
1101         try {
1102             $return = mod_glossary_external::get_entry_by_id($e4->id);
1103             $this->fail('Cannot view entries from another course.');
1104         } catch (require_login_exception $e) {
1105             // All good.
1106         }
1108         // An admin can be other's entries to be approved.
1109         $this->setAdminUser();
1110         $return = mod_glossary_external::get_entry_by_id($e3->id);
1111         $return = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $return);
1112         $this->assertEquals($e3->id, $return['entry']['id']);
1113     }
1115     public function test_add_entry_without_optional_settings() {
1116         global $CFG, $DB;
1117         $this->resetAfterTest(true);
1119         $course = $this->getDataGenerator()->create_course();
1120         $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
1122         $this->setAdminUser();
1123         $concept = 'A concept';
1124         $definition = '<p>A definition</p>';
1125         $return = mod_glossary_external::add_entry($glossary->id, $concept, $definition, FORMAT_HTML);
1126         $return = external_api::clean_returnvalue(mod_glossary_external::add_entry_returns(), $return);
1128         // Get entry from DB.
1129         $entry = $DB->get_record('glossary_entries', array('id' => $return['entryid']));
1131         $this->assertEquals($concept, $entry->concept);
1132         $this->assertEquals($definition, $entry->definition);
1133         $this->assertEquals($CFG->glossary_linkentries, $entry->usedynalink);
1134         $this->assertEquals($CFG->glossary_casesensitive, $entry->casesensitive);
1135         $this->assertEquals($CFG->glossary_fullmatch, $entry->fullmatch);
1136         $this->assertEmpty($DB->get_records('glossary_alias', array('entryid' => $return['entryid'])));
1137         $this->assertEmpty($DB->get_records('glossary_entries_categories', array('entryid' => $return['entryid'])));
1138     }
1140     public function test_add_entry_with_aliases() {
1141         global $DB;
1142         $this->resetAfterTest(true);
1144         $course = $this->getDataGenerator()->create_course();
1145         $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
1147         $this->setAdminUser();
1148         $concept = 'A concept';
1149         $definition = 'A definition';
1150         $paramaliases = 'abc, def, gez';
1151         $options = array(
1152             array(
1153                 'name' => 'aliases',
1154                 'value' => $paramaliases,
1155             )
1156         );
1157         $return = mod_glossary_external::add_entry($glossary->id, $concept, $definition, FORMAT_HTML, $options);
1158         $return = external_api::clean_returnvalue(mod_glossary_external::add_entry_returns(), $return);
1160         $aliases = $DB->get_records('glossary_alias', array('entryid' => $return['entryid']));
1161         $this->assertCount(3, $aliases);
1162         foreach ($aliases as $alias) {
1163             $this->assertContains($alias->alias, $paramaliases);
1164         }
1165     }
1167     public function test_add_entry_in_categories() {
1168         global $DB;
1169         $this->resetAfterTest(true);
1171         $course = $this->getDataGenerator()->create_course();
1172         $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
1173         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
1174         $cat1 = $gg->create_category($glossary);
1175         $cat2 = $gg->create_category($glossary);
1177         $this->setAdminUser();
1178         $concept = 'A concept';
1179         $definition = 'A definition';
1180         $paramcategories = "$cat1->id, $cat2->id";
1181         $options = array(
1182             array(
1183                 'name' => 'categories',
1184                 'value' => $paramcategories,
1185             )
1186         );
1187         $return = mod_glossary_external::add_entry($glossary->id, $concept, $definition, FORMAT_HTML, $options);
1188         $return = external_api::clean_returnvalue(mod_glossary_external::add_entry_returns(), $return);
1190         $categories = $DB->get_records('glossary_entries_categories', array('entryid' => $return['entryid']));
1191         $this->assertCount(2, $categories);
1192         foreach ($categories as $category) {
1193             $this->assertContains($category->categoryid, $paramcategories);
1194         }
1195     }
1197     public function test_add_entry_with_attachments() {
1198         global $DB, $USER;
1199         $this->resetAfterTest(true);
1201         $course = $this->getDataGenerator()->create_course();
1202         $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
1203         $context = context_module::instance($glossary->cmid);
1205         $this->setAdminUser();
1206         $concept = 'A concept';
1207         $definition = 'A definition';
1209         // Draft files.
1210         $draftidinlineattach = file_get_unused_draft_itemid();
1211         $draftidattach = file_get_unused_draft_itemid();
1212         $usercontext = context_user::instance($USER->id);
1213         $filerecordinline = array(
1214             'contextid' => $usercontext->id,
1215             'component' => 'user',
1216             'filearea'  => 'draft',
1217             'itemid'    => $draftidinlineattach,
1218             'filepath'  => '/',
1219             'filename'  => 'shouldbeanimage.txt',
1220         );
1221         $fs = get_file_storage();
1223         // Create a file in a draft area for regular attachments.
1224         $filerecordattach = $filerecordinline;
1225         $attachfilename = 'attachment.txt';
1226         $filerecordattach['filename'] = $attachfilename;
1227         $filerecordattach['itemid'] = $draftidattach;
1228         $fs->create_file_from_string($filerecordinline, 'image contents (not really)');
1229         $fs->create_file_from_string($filerecordattach, 'simple text attachment');
1231         $options = array(
1232             array(
1233                 'name' => 'inlineattachmentsid',
1234                 'value' => $draftidinlineattach,
1235             ),
1236             array(
1237                 'name' => 'attachmentsid',
1238                 'value' => $draftidattach,
1239             )
1240         );
1241         $return = mod_glossary_external::add_entry($glossary->id, $concept, $definition, FORMAT_HTML, $options);
1242         $return = external_api::clean_returnvalue(mod_glossary_external::add_entry_returns(), $return);
1244         $editorfiles = external_util::get_area_files($context->id, 'mod_glossary', 'entry', $return['entryid']);
1245         $attachmentfiles = external_util::get_area_files($context->id, 'mod_glossary', 'attachment', $return['entryid']);
1247         $this->assertCount(1, $editorfiles);
1248         $this->assertCount(1, $attachmentfiles);
1250         $this->assertEquals('shouldbeanimage.txt', $editorfiles[0]['filename']);
1251         $this->assertEquals('attachment.txt', $attachmentfiles[0]['filename']);
1252     }
1254     /**
1255      *   Test get entry including rating information.
1256      */
1257     public function test_get_entry_rating_information() {
1258         $this->resetAfterTest(true);
1260         global $DB, $CFG;
1261         require_once($CFG->dirroot . '/rating/lib.php');
1263         $this->resetAfterTest(true);
1265         $user1 = self::getDataGenerator()->create_user();
1266         $user2 = self::getDataGenerator()->create_user();
1267         $user3 = self::getDataGenerator()->create_user();
1268         $teacher = self::getDataGenerator()->create_user();
1270         // Create course to add the module.
1271         $course = self::getDataGenerator()->create_course();
1273         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
1274         $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
1275         $this->getDataGenerator()->enrol_user($user1->id, $course->id, $studentrole->id, 'manual');
1276         $this->getDataGenerator()->enrol_user($user2->id, $course->id, $studentrole->id, 'manual');
1277         $this->getDataGenerator()->enrol_user($user3->id, $course->id, $studentrole->id, 'manual');
1278         $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
1280         // Create the glossary and contents.
1281         $record = new stdClass();
1282         $record->course = $course->id;
1283         $record->assessed = RATING_AGGREGATE_AVERAGE;
1284         $scale = $this->getDataGenerator()->create_scale(array('scale' => 'A,B,C,D'));
1285         $record->scale = "-$scale->id";
1286         $glossary = $this->getDataGenerator()->create_module('glossary', $record);
1287         $context = context_module::instance($glossary->cmid);
1289         $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
1290         $entry = $gg->create_content($glossary, array('approved' => 1, 'userid' => $user1->id));
1292         // Rate the entry as user2.
1293         $rating1 = new stdClass();
1294         $rating1->contextid = $context->id;
1295         $rating1->component = 'mod_glossary';
1296         $rating1->ratingarea = 'entry';
1297         $rating1->itemid = $entry->id;
1298         $rating1->rating = 1; // 1 is A.
1299         $rating1->scaleid = "-$scale->id";
1300         $rating1->userid = $user2->id;
1301         $rating1->timecreated = time();
1302         $rating1->timemodified = time();
1303         $rating1->id = $DB->insert_record('rating', $rating1);
1305         // Rate the entry as user3.
1306         $rating2 = new stdClass();
1307         $rating2->contextid = $context->id;
1308         $rating2->component = 'mod_glossary';
1309         $rating2->ratingarea = 'entry';
1310         $rating2->itemid = $entry->id;
1311         $rating2->rating = 3; // 3 is C.
1312         $rating2->scaleid = "-$scale->id";
1313         $rating2->userid = $user3->id;
1314         $rating2->timecreated = time() + 1;
1315         $rating2->timemodified = time() + 1;
1316         $rating2->id = $DB->insert_record('rating', $rating2);
1318         // As student, retrieve ratings information.
1319         $this->setUser($user1);
1320         $result = mod_glossary_external::get_entry_by_id($entry->id);
1321         $result = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $result);
1322         $this->assertCount(1, $result['ratinginfo']['ratings']);
1323         $this->assertFalse($result['ratinginfo']['ratings'][0]['canviewaggregate']);
1324         $this->assertFalse($result['ratinginfo']['canviewall']);
1325         $this->assertFalse($result['ratinginfo']['ratings'][0]['canrate']);
1326         $this->assertTrue(!isset($result['ratinginfo']['ratings'][0]['count']));
1328         // Now, as teacher, I should see the info correctly.
1329         $this->setUser($teacher);
1330         $result = mod_glossary_external::get_entry_by_id($entry->id);
1331         $result = external_api::clean_returnvalue(mod_glossary_external::get_entry_by_id_returns(), $result);
1332         $this->assertCount(1, $result['ratinginfo']['ratings']);
1333         $this->assertTrue($result['ratinginfo']['ratings'][0]['canviewaggregate']);
1334         $this->assertTrue($result['ratinginfo']['canviewall']);
1335         $this->assertTrue($result['ratinginfo']['ratings'][0]['canrate']);
1336         $this->assertEquals(2, $result['ratinginfo']['ratings'][0]['count']);
1337         $this->assertEquals(2, $result['ratinginfo']['ratings'][0]['aggregate']);   // 2 is B, that is the average of A + C.
1338     }