MDL-51685 unittest: Test functionality individually
[moodle.git] / user / tests / externallib_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * User external PHPunit tests
19  *
20  * @package    core_user
21  * @category   external
22  * @copyright  2012 Jerome Mouneyrac
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  * @since Moodle 2.4
25  */
27 defined('MOODLE_INTERNAL') || die();
29 global $CFG;
31 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32 require_once($CFG->dirroot . '/user/externallib.php');
33 require_once($CFG->dirroot . '/files/externallib.php');
35 class core_user_externallib_testcase extends externallib_advanced_testcase {
37     /**
38      * Test get_users
39      */
40     public function test_get_users() {
41         global $USER, $CFG;
43         $this->resetAfterTest(true);
45         $course = self::getDataGenerator()->create_course();
47         $user1 = array(
48             'username' => 'usernametest1',
49             'idnumber' => 'idnumbertest1',
50             'firstname' => 'First Name User Test 1',
51             'lastname' => 'Last Name User Test 1',
52             'email' => 'usertest1@example.com',
53             'address' => '2 Test Street Perth 6000 WA',
54             'phone1' => '01010101010',
55             'phone2' => '02020203',
56             'icq' => 'testuser1',
57             'skype' => 'testuser1',
58             'yahoo' => 'testuser1',
59             'aim' => 'testuser1',
60             'msn' => 'testuser1',
61             'department' => 'Department of user 1',
62             'institution' => 'Institution of user 1',
63             'description' => 'This is a description for user 1',
64             'descriptionformat' => FORMAT_MOODLE,
65             'city' => 'Perth',
66             'url' => 'http://moodle.org',
67             'country' => 'au'
68             );
70         $user1 = self::getDataGenerator()->create_user($user1);
71         set_config('usetags', 1);
72         require_once($CFG->dirroot . '/user/editlib.php');
73         require_once($CFG->dirroot . '/tag/lib.php');
74         $user1->interests = array('Cinema', 'Tennis', 'Dance', 'Guitar', 'Cooking');
75         useredit_update_interests($user1, $user1->interests);
77         $user2 = self::getDataGenerator()->create_user(
78                 array('username' => 'usernametest2', 'idnumber' => 'idnumbertest2'));
80         $generatedusers = array();
81         $generatedusers[$user1->id] = $user1;
82         $generatedusers[$user2->id] = $user2;
84         $context = context_course::instance($course->id);
85         $roleid = $this->assignUserCapability('moodle/user:viewdetails', $context->id);
87         // Enrol the users in the course.
88         $this->getDataGenerator()->enrol_user($user1->id, $course->id, $roleid);
89         $this->getDataGenerator()->enrol_user($user2->id, $course->id, $roleid);
90         $this->getDataGenerator()->enrol_user($USER->id, $course->id, $roleid);
92         // call as admin and receive all possible fields.
93         $this->setAdminUser();
95         $searchparams = array(
96             array('key' => 'invalidkey', 'value' => 'invalidkey'),
97             array('key' => 'email', 'value' => $user1->email),
98             array('key' => 'firstname', 'value' => $user1->firstname));
100         // Call the external function.
101         $result = core_user_external::get_users($searchparams);
103         // We need to execute the return values cleaning process to simulate the web service server
104         $result = external_api::clean_returnvalue(core_user_external::get_users_returns(), $result);
106         // Check we retrieve the good total number of enrolled users + no error on capability.
107         $expectedreturnedusers = 1;
108         $returnedusers = $result['users'];
109         $this->assertEquals($expectedreturnedusers, count($returnedusers));
111         foreach($returnedusers as $returneduser) {
112             $generateduser = ($returneduser['id'] == $USER->id) ?
113                                 $USER : $generatedusers[$returneduser['id']];
114             $this->assertEquals($generateduser->username, $returneduser['username']);
115             if (!empty($generateduser->idnumber)) {
116                 $this->assertEquals($generateduser->idnumber, $returneduser['idnumber']);
117             }
118             $this->assertEquals($generateduser->firstname, $returneduser['firstname']);
119             $this->assertEquals($generateduser->lastname, $returneduser['lastname']);
120             if ($generateduser->email != $USER->email) { // Don't check the tmp modified $USER email.
121                 $this->assertEquals($generateduser->email, $returneduser['email']);
122             }
123             if (!empty($generateduser->address)) {
124                 $this->assertEquals($generateduser->address, $returneduser['address']);
125             }
126             if (!empty($generateduser->phone1)) {
127                 $this->assertEquals($generateduser->phone1, $returneduser['phone1']);
128             }
129             if (!empty($generateduser->phone2)) {
130                 $this->assertEquals($generateduser->phone2, $returneduser['phone2']);
131             }
132             if (!empty($generateduser->icq)) {
133                 $this->assertEquals($generateduser->icq, $returneduser['icq']);
134             }
135             if (!empty($generateduser->skype)) {
136                 $this->assertEquals($generateduser->skype, $returneduser['skype']);
137             }
138             if (!empty($generateduser->yahoo)) {
139                 $this->assertEquals($generateduser->yahoo, $returneduser['yahoo']);
140             }
141             if (!empty($generateduser->aim)) {
142                 $this->assertEquals($generateduser->aim, $returneduser['aim']);
143             }
144             if (!empty($generateduser->msn)) {
145                 $this->assertEquals($generateduser->msn, $returneduser['msn']);
146             }
147             if (!empty($generateduser->department)) {
148                 $this->assertEquals($generateduser->department, $returneduser['department']);
149             }
150             if (!empty($generateduser->institution)) {
151                 $this->assertEquals($generateduser->institution, $returneduser['institution']);
152             }
153             if (!empty($generateduser->description)) {
154                 $this->assertEquals($generateduser->description, $returneduser['description']);
155             }
156             if (!empty($generateduser->descriptionformat)) {
157                 $this->assertEquals(FORMAT_HTML, $returneduser['descriptionformat']);
158             }
159             if (!empty($generateduser->city)) {
160                 $this->assertEquals($generateduser->city, $returneduser['city']);
161             }
162             if (!empty($generateduser->country)) {
163                 $this->assertEquals($generateduser->country, $returneduser['country']);
164             }
165             if (!empty($generateduser->url)) {
166                 $this->assertEquals($generateduser->url, $returneduser['url']);
167             }
168             if (!empty($CFG->usetags) and !empty($generateduser->interests)) {
169                 $this->assertEquals(implode(', ', $generateduser->interests), $returneduser['interests']);
170             }
171         }
173         // Test the invalid key warning.
174         $warnings = $result['warnings'];
175         $this->assertEquals(count($warnings), 1);
176         $warning = array_pop($warnings);
177         $this->assertEquals($warning['item'], 'invalidkey');
178         $this->assertEquals($warning['warningcode'], 'invalidfieldparameter');
180         // Test sending twice the same search field.
181         try {
182             $searchparams = array(
183             array('key' => 'firstname', 'value' => 'Canard'),
184             array('key' => 'email', 'value' => $user1->email),
185             array('key' => 'firstname', 'value' => $user1->firstname));
187             // Call the external function.
188             $result = core_user_external::get_users($searchparams);
189             $this->fail('Expecting \'keyalreadyset\' moodle_exception to be thrown.');
190         } catch (moodle_exception $e) {
191             $this->assertEquals('keyalreadyset', $e->errorcode);
192         } catch (Exception $e) {
193             $this->fail('Expecting \'keyalreadyset\' moodle_exception to be thrown.');
194         }
195     }
197     /**
198      * Test get_users_by_field
199      */
200     public function test_get_users_by_field() {
201         global $USER, $CFG;
203         $this->resetAfterTest(true);
205         $course = self::getDataGenerator()->create_course();
206         $user1 = array(
207             'username' => 'usernametest1',
208             'idnumber' => 'idnumbertest1',
209             'firstname' => 'First Name User Test 1',
210             'lastname' => 'Last Name User Test 1',
211             'email' => 'usertest1@example.com',
212             'address' => '2 Test Street Perth 6000 WA',
213             'phone1' => '01010101010',
214             'phone2' => '02020203',
215             'icq' => 'testuser1',
216             'skype' => 'testuser1',
217             'yahoo' => 'testuser1',
218             'aim' => 'testuser1',
219             'msn' => 'testuser1',
220             'department' => 'Department of user 1',
221             'institution' => 'Institution of user 1',
222             'description' => 'This is a description for user 1',
223             'descriptionformat' => FORMAT_MOODLE,
224             'city' => 'Perth',
225             'url' => 'http://moodle.org',
226             'country' => 'au'
227             );
228         $user1 = self::getDataGenerator()->create_user($user1);
229         if (!empty($CFG->usetags)) {
230             require_once($CFG->dirroot . '/user/editlib.php');
231             require_once($CFG->dirroot . '/tag/lib.php');
232             $user1->interests = array('Cinema', 'Tennis', 'Dance', 'Guitar', 'Cooking');
233             useredit_update_interests($user1, $user1->interests);
234         }
235         $user2 = self::getDataGenerator()->create_user(
236                 array('username' => 'usernametest2', 'idnumber' => 'idnumbertest2'));
238         $generatedusers = array();
239         $generatedusers[$user1->id] = $user1;
240         $generatedusers[$user2->id] = $user2;
242         $context = context_course::instance($course->id);
243         $roleid = $this->assignUserCapability('moodle/user:viewdetails', $context->id);
245         // Enrol the users in the course.
246         $this->getDataGenerator()->enrol_user($user1->id, $course->id, $roleid, 'manual');
247         $this->getDataGenerator()->enrol_user($user2->id, $course->id, $roleid, 'manual');
248         $this->getDataGenerator()->enrol_user($USER->id, $course->id, $roleid, 'manual');
250         // call as admin and receive all possible fields.
251         $this->setAdminUser();
253         $fieldstosearch = array('id', 'idnumber', 'username', 'email');
255         foreach ($fieldstosearch as $fieldtosearch) {
257             // Call the external function.
258             $returnedusers = core_user_external::get_users_by_field($fieldtosearch,
259                         array($USER->{$fieldtosearch}, $user1->{$fieldtosearch}, $user2->{$fieldtosearch}));
260             $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_field_returns(), $returnedusers);
262             // Expected result differ following the searched field
263             // Admin user in the PHPunit framework doesn't have an idnumber.
264             if ($fieldtosearch == 'idnumber') {
265                 $expectedreturnedusers = 2;
266             } else {
267                 $expectedreturnedusers = 3;
268             }
270             // Check we retrieve the good total number of enrolled users + no error on capability.
271             $this->assertEquals($expectedreturnedusers, count($returnedusers));
273             foreach($returnedusers as $returneduser) {
274                 $generateduser = ($returneduser['id'] == $USER->id) ?
275                                     $USER : $generatedusers[$returneduser['id']];
276                 $this->assertEquals($generateduser->username, $returneduser['username']);
277                 if (!empty($generateduser->idnumber)) {
278                     $this->assertEquals($generateduser->idnumber, $returneduser['idnumber']);
279                 }
280                 $this->assertEquals($generateduser->firstname, $returneduser['firstname']);
281                 $this->assertEquals($generateduser->lastname, $returneduser['lastname']);
282                 if ($generateduser->email != $USER->email) { //don't check the tmp modified $USER email
283                     $this->assertEquals($generateduser->email, $returneduser['email']);
284                 }
285                 if (!empty($generateduser->address)) {
286                     $this->assertEquals($generateduser->address, $returneduser['address']);
287                 }
288                 if (!empty($generateduser->phone1)) {
289                     $this->assertEquals($generateduser->phone1, $returneduser['phone1']);
290                 }
291                 if (!empty($generateduser->phone2)) {
292                     $this->assertEquals($generateduser->phone2, $returneduser['phone2']);
293                 }
294                 if (!empty($generateduser->icq)) {
295                     $this->assertEquals($generateduser->icq, $returneduser['icq']);
296                 }
297                 if (!empty($generateduser->skype)) {
298                     $this->assertEquals($generateduser->skype, $returneduser['skype']);
299                 }
300                 if (!empty($generateduser->yahoo)) {
301                     $this->assertEquals($generateduser->yahoo, $returneduser['yahoo']);
302                 }
303                 if (!empty($generateduser->aim)) {
304                     $this->assertEquals($generateduser->aim, $returneduser['aim']);
305                 }
306                 if (!empty($generateduser->msn)) {
307                     $this->assertEquals($generateduser->msn, $returneduser['msn']);
308                 }
309                 if (!empty($generateduser->department)) {
310                     $this->assertEquals($generateduser->department, $returneduser['department']);
311                 }
312                 if (!empty($generateduser->institution)) {
313                     $this->assertEquals($generateduser->institution, $returneduser['institution']);
314                 }
315                 if (!empty($generateduser->description)) {
316                     $this->assertEquals($generateduser->description, $returneduser['description']);
317                 }
318                 if (!empty($generateduser->descriptionformat) and isset($returneduser['descriptionformat'])) {
319                     $this->assertEquals($generateduser->descriptionformat, $returneduser['descriptionformat']);
320                 }
321                 if (!empty($generateduser->city)) {
322                     $this->assertEquals($generateduser->city, $returneduser['city']);
323                 }
324                 if (!empty($generateduser->country)) {
325                     $this->assertEquals($generateduser->country, $returneduser['country']);
326                 }
327                 if (!empty($generateduser->url)) {
328                     $this->assertEquals($generateduser->url, $returneduser['url']);
329                 }
330                 if (!empty($CFG->usetags) and !empty($generateduser->interests)) {
331                     $this->assertEquals(implode(', ', $generateduser->interests), $returneduser['interests']);
332                 }
333             }
334         }
336         // Test that no result are returned for search by username if we are not admin
337         $this->setGuestUser();
339         // Call the external function.
340         $returnedusers = core_user_external::get_users_by_field('username',
341                     array($USER->username, $user1->username, $user2->username));
342         $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_field_returns(), $returnedusers);
344         // Only the own $USER username should be returned
345         $this->assertEquals(1, count($returnedusers));
347         // And finally test as one of the enrolled users.
348         $this->setUser($user1);
350         // Call the external function.
351         $returnedusers = core_user_external::get_users_by_field('username',
352             array($USER->username, $user1->username, $user2->username));
353         $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_field_returns(), $returnedusers);
355         // Only the own $USER username should be returned still.
356         $this->assertEquals(1, count($returnedusers));
357     }
359     public function get_course_user_profiles_setup($capability) {
360         global $USER, $CFG;
362         $this->resetAfterTest(true);
364         $return = new stdClass();
366         // Create the course and fetch its context.
367         $return->course = self::getDataGenerator()->create_course();
368         $return->user1 = array(
369             'username' => 'usernametest1',
370             'idnumber' => 'idnumbertest1',
371             'firstname' => 'First Name User Test 1',
372             'lastname' => 'Last Name User Test 1',
373             'email' => 'usertest1@example.com',
374             'address' => '2 Test Street Perth 6000 WA',
375             'phone1' => '01010101010',
376             'phone2' => '02020203',
377             'icq' => 'testuser1',
378             'skype' => 'testuser1',
379             'yahoo' => 'testuser1',
380             'aim' => 'testuser1',
381             'msn' => 'testuser1',
382             'department' => 'Department of user 1',
383             'institution' => 'Institution of user 1',
384             'description' => 'This is a description for user 1',
385             'descriptionformat' => FORMAT_MOODLE,
386             'city' => 'Perth',
387             'url' => 'http://moodle.org',
388             'country' => 'au'
389         );
390         $return->user1 = self::getDataGenerator()->create_user($return->user1);
391         if (!empty($CFG->usetags)) {
392             require_once($CFG->dirroot . '/user/editlib.php');
393             require_once($CFG->dirroot . '/tag/lib.php');
394             $return->user1->interests = array('Cinema', 'Tennis', 'Dance', 'Guitar', 'Cooking');
395             useredit_update_interests($return->user1, $return->user1->interests);
396         }
397         $return->user2 = self::getDataGenerator()->create_user();
399         $context = context_course::instance($return->course->id);
400         $return->roleid = $this->assignUserCapability($capability, $context->id);
402         // Enrol the users in the course.
403         $this->getDataGenerator()->enrol_user($return->user1->id, $return->course->id, $return->roleid, 'manual');
404         $this->getDataGenerator()->enrol_user($return->user2->id, $return->course->id, $return->roleid, 'manual');
405         $this->getDataGenerator()->enrol_user($USER->id, $return->course->id, $return->roleid, 'manual');
407         return $return;
408     }
410     /**
411      * Test get_course_user_profiles
412      */
413     public function test_get_course_user_profiles() {
414         global $USER, $CFG;
416         $this->resetAfterTest(true);
418         $data = $this->get_course_user_profiles_setup('moodle/user:viewdetails');
420         // Call the external function.
421         $enrolledusers = core_user_external::get_course_user_profiles(array(
422                     array('userid' => $USER->id, 'courseid' => $data->course->id)));
424         // We need to execute the return values cleaning process to simulate the web service server.
425         $enrolledusers = external_api::clean_returnvalue(core_user_external::get_course_user_profiles_returns(), $enrolledusers);
427         // Check we retrieve the good total number of enrolled users + no error on capability.
428         $this->assertEquals(1, count($enrolledusers));
429     }
431     public function test_get_user_course_profile_as_admin() {
432         global $USER, $CFG;
434         global $USER, $CFG;
436         $this->resetAfterTest(true);
438         $data = $this->get_course_user_profiles_setup('moodle/user:viewdetails');
440         // Do the same call as admin to receive all possible fields.
441         $this->setAdminUser();
442         $USER->email = "admin@example.com";
444         // Call the external function.
445         $enrolledusers = core_user_external::get_course_user_profiles(array(
446             array('userid' => $data->user1->id, 'courseid' => $data->course->id)));
448         // We need to execute the return values cleaning process to simulate the web service server.
449         $enrolledusers = external_api::clean_returnvalue(core_user_external::get_course_user_profiles_returns(), $enrolledusers);
451         foreach($enrolledusers as $enrolleduser) {
452             if ($enrolleduser['username'] == $data->user1->username) {
453                 $this->assertEquals($data->user1->idnumber, $enrolleduser['idnumber']);
454                 $this->assertEquals($data->user1->firstname, $enrolleduser['firstname']);
455                 $this->assertEquals($data->user1->lastname, $enrolleduser['lastname']);
456                 $this->assertEquals($data->user1->email, $enrolleduser['email']);
457                 $this->assertEquals($data->user1->address, $enrolleduser['address']);
458                 $this->assertEquals($data->user1->phone1, $enrolleduser['phone1']);
459                 $this->assertEquals($data->user1->phone2, $enrolleduser['phone2']);
460                 $this->assertEquals($data->user1->icq, $enrolleduser['icq']);
461                 $this->assertEquals($data->user1->skype, $enrolleduser['skype']);
462                 $this->assertEquals($data->user1->yahoo, $enrolleduser['yahoo']);
463                 $this->assertEquals($data->user1->aim, $enrolleduser['aim']);
464                 $this->assertEquals($data->user1->msn, $enrolleduser['msn']);
465                 $this->assertEquals($data->user1->department, $enrolleduser['department']);
466                 $this->assertEquals($data->user1->institution, $enrolleduser['institution']);
467                 $this->assertEquals($data->user1->description, $enrolleduser['description']);
468                 $this->assertEquals(FORMAT_HTML, $enrolleduser['descriptionformat']);
469                 $this->assertEquals($data->user1->city, $enrolleduser['city']);
470                 $this->assertEquals($data->user1->country, $enrolleduser['country']);
471                 $this->assertEquals($data->user1->url, $enrolleduser['url']);
472                 if (!empty($CFG->usetags)) {
473                     $this->assertEquals(implode(', ', $data->user1->interests), $enrolleduser['interests']);
474                 }
475             }
476         }
477     }
479     /**
480      * Test create_users
481      */
482     public function test_create_users() {
483          global $USER, $CFG, $DB;
485         $this->resetAfterTest(true);
487         $user1 = array(
488             'username' => 'usernametest1',
489             'password' => 'Moodle2012!',
490             'idnumber' => 'idnumbertest1',
491             'firstname' => 'First Name User Test 1',
492             'lastname' => 'Last Name User Test 1',
493             'middlename' => 'Middle Name User Test 1',
494             'lastnamephonetic' => '最後のお名前のテスト一号',
495             'firstnamephonetic' => 'お名前のテスト一号',
496             'alternatename' => 'Alternate Name User Test 1',
497             'email' => 'usertest1@example.com',
498             'description' => 'This is a description for user 1',
499             'city' => 'Perth',
500             'country' => 'au'
501             );
503         $context = context_system::instance();
504         $roleid = $this->assignUserCapability('moodle/user:create', $context->id);
506         // Call the external function.
507         $createdusers = core_user_external::create_users(array($user1));
509         // We need to execute the return values cleaning process to simulate the web service server.
510         $createdusers = external_api::clean_returnvalue(core_user_external::create_users_returns(), $createdusers);
512         // Check we retrieve the good total number of created users + no error on capability.
513         $this->assertEquals(1, count($createdusers));
515         foreach($createdusers as $createduser) {
516             $dbuser = $DB->get_record('user', array('id' => $createduser['id']));
517             $this->assertEquals($dbuser->username, $user1['username']);
518             $this->assertEquals($dbuser->idnumber, $user1['idnumber']);
519             $this->assertEquals($dbuser->firstname, $user1['firstname']);
520             $this->assertEquals($dbuser->lastname, $user1['lastname']);
521             $this->assertEquals($dbuser->email, $user1['email']);
522             $this->assertEquals($dbuser->description, $user1['description']);
523             $this->assertEquals($dbuser->city, $user1['city']);
524             $this->assertEquals($dbuser->country, $user1['country']);
525         }
527         // Call without required capability
528         $this->unassignUserCapability('moodle/user:create', $context->id, $roleid);
529         $this->setExpectedException('required_capability_exception');
530         $createdusers = core_user_external::create_users(array($user1));
531     }
533     /**
534      * Test delete_users
535      */
536     public function test_delete_users() {
537         global $USER, $CFG, $DB;
539         $this->resetAfterTest(true);
541         $user1 = self::getDataGenerator()->create_user();
542         $user2 = self::getDataGenerator()->create_user();
544         // Check the users were correctly created.
545         $this->assertEquals(2, $DB->count_records_select('user', 'deleted = 0 AND (id = :userid1 OR id = :userid2)',
546                 array('userid1' => $user1->id, 'userid2' => $user2->id)));
548         $context = context_system::instance();
549         $roleid = $this->assignUserCapability('moodle/user:delete', $context->id);
551         // Call the external function.
552         core_user_external::delete_users(array($user1->id, $user2->id));
554         // Check we retrieve no users + no error on capability.
555         $this->assertEquals(0, $DB->count_records_select('user', 'deleted = 0 AND (id = :userid1 OR id = :userid2)',
556                 array('userid1' => $user1->id, 'userid2' => $user2->id)));
558         // Call without required capability.
559         $this->unassignUserCapability('moodle/user:delete', $context->id, $roleid);
560         $this->setExpectedException('required_capability_exception');
561         core_user_external::delete_users(array($user1->id, $user2->id));
562     }
564     /**
565      * Test get_users_by_id
566      */
567     public function test_get_users_by_id() {
568         global $USER, $CFG;
570         $this->resetAfterTest(true);
572         $user1 = array(
573             'username' => 'usernametest1',
574             'idnumber' => 'idnumbertest1',
575             'firstname' => 'First Name User Test 1',
576             'lastname' => 'Last Name User Test 1',
577             'email' => 'usertest1@example.com',
578             'address' => '2 Test Street Perth 6000 WA',
579             'phone1' => '01010101010',
580             'phone2' => '02020203',
581             'icq' => 'testuser1',
582             'skype' => 'testuser1',
583             'yahoo' => 'testuser1',
584             'aim' => 'testuser1',
585             'msn' => 'testuser1',
586             'department' => 'Department of user 1',
587             'institution' => 'Institution of user 1',
588             'description' => 'This is a description for user 1',
589             'descriptionformat' => FORMAT_MOODLE,
590             'city' => 'Perth',
591             'url' => 'http://moodle.org',
592             'country' => 'au'
593             );
594         $user1 = self::getDataGenerator()->create_user($user1);
595         if (!empty($CFG->usetags)) {
596             require_once($CFG->dirroot . '/user/editlib.php');
597             require_once($CFG->dirroot . '/tag/lib.php');
598             $user1->interests = array('Cinema', 'Tennis', 'Dance', 'Guitar', 'Cooking');
599             useredit_update_interests($user1, $user1->interests);
600         }
601         $user2 = self::getDataGenerator()->create_user();
603         $context = context_system::instance();
604         $roleid = $this->assignUserCapability('moodle/user:viewdetails', $context->id);
606         // Call the external function.
607         $returnedusers = core_user_external::get_users_by_id(array(
608                     $USER->id, $user1->id, $user2->id));
610         // We need to execute the return values cleaning process to simulate the web service server.
611         $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_id_returns(), $returnedusers);
613         // Check we retrieve the good total number of enrolled users + no error on capability.
614         $this->assertEquals(3, count($returnedusers));
616         // Do the same call as admin to receive all possible fields.
617         $this->setAdminUser();
618         $USER->email = "admin@example.com";
620         // Call the external function.
621         $returnedusers = core_user_external::get_users_by_id(array(
622                     $USER->id, $user1->id, $user2->id));
624         // We need to execute the return values cleaning process to simulate the web service server.
625         $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_id_returns(), $returnedusers);
627         foreach($returnedusers as $enrolleduser) {
628             if ($enrolleduser['username'] == $user1->username) {
629                 $this->assertEquals($user1->idnumber, $enrolleduser['idnumber']);
630                 $this->assertEquals($user1->firstname, $enrolleduser['firstname']);
631                 $this->assertEquals($user1->lastname, $enrolleduser['lastname']);
632                 $this->assertEquals($user1->email, $enrolleduser['email']);
633                 $this->assertEquals($user1->address, $enrolleduser['address']);
634                 $this->assertEquals($user1->phone1, $enrolleduser['phone1']);
635                 $this->assertEquals($user1->phone2, $enrolleduser['phone2']);
636                 $this->assertEquals($user1->icq, $enrolleduser['icq']);
637                 $this->assertEquals($user1->skype, $enrolleduser['skype']);
638                 $this->assertEquals($user1->yahoo, $enrolleduser['yahoo']);
639                 $this->assertEquals($user1->aim, $enrolleduser['aim']);
640                 $this->assertEquals($user1->msn, $enrolleduser['msn']);
641                 $this->assertEquals($user1->department, $enrolleduser['department']);
642                 $this->assertEquals($user1->institution, $enrolleduser['institution']);
643                 $this->assertEquals($user1->description, $enrolleduser['description']);
644                 $this->assertEquals(FORMAT_HTML, $enrolleduser['descriptionformat']);
645                 $this->assertEquals($user1->city, $enrolleduser['city']);
646                 $this->assertEquals($user1->country, $enrolleduser['country']);
647                 $this->assertEquals($user1->url, $enrolleduser['url']);
648                 if (!empty($CFG->usetags)) {
649                     $this->assertEquals(implode(', ', $user1->interests), $enrolleduser['interests']);
650                 }
651             }
652         }
653     }
655     /**
656      * Test update_users
657      */
658     public function test_update_users() {
659         global $USER, $CFG, $DB;
661         $this->resetAfterTest(true);
663         $user1 = self::getDataGenerator()->create_user();
665         $user1 = array(
666             'id' => $user1->id,
667             'username' => 'usernametest1',
668             'password' => 'Moodle2012!',
669             'idnumber' => 'idnumbertest1',
670             'firstname' => 'First Name User Test 1',
671             'lastname' => 'Last Name User Test 1',
672             'middlename' => 'Middle Name User Test 1',
673             'lastnamephonetic' => '最後のお名前のテスト一号',
674             'firstnamephonetic' => 'お名前のテスト一号',
675             'alternatename' => 'Alternate Name User Test 1',
676             'email' => 'usertest1@example.com',
677             'description' => 'This is a description for user 1',
678             'city' => 'Perth',
679             'country' => 'au'
680             );
682         $context = context_system::instance();
683         $roleid = $this->assignUserCapability('moodle/user:update', $context->id);
685         // Call the external function.
686         core_user_external::update_users(array($user1));
688         $dbuser = $DB->get_record('user', array('id' => $user1['id']));
689         $this->assertEquals($dbuser->username, $user1['username']);
690         $this->assertEquals($dbuser->idnumber, $user1['idnumber']);
691         $this->assertEquals($dbuser->firstname, $user1['firstname']);
692         $this->assertEquals($dbuser->lastname, $user1['lastname']);
693         $this->assertEquals($dbuser->email, $user1['email']);
694         $this->assertEquals($dbuser->description, $user1['description']);
695         $this->assertEquals($dbuser->city, $user1['city']);
696         $this->assertEquals($dbuser->country, $user1['country']);
698         // Call without required capability.
699         $this->unassignUserCapability('moodle/user:update', $context->id, $roleid);
700         $this->setExpectedException('required_capability_exception');
701         core_user_external::update_users(array($user1));
702     }
704     /**
705      * Test add_user_private_files
706      */
707     public function test_add_user_private_files() {
708         global $USER, $CFG, $DB;
710         $this->resetAfterTest(true);
712         $context = context_system::instance();
713         $roleid = $this->assignUserCapability('moodle/user:manageownfiles', $context->id);
715         $context = context_user::instance($USER->id);
716         $contextid = $context->id;
717         $component = "user";
718         $filearea = "draft";
719         $itemid = 0;
720         $filepath = "/";
721         $filename = "Simple.txt";
722         $filecontent = base64_encode("Let us create a nice simple file");
723         $contextlevel = null;
724         $instanceid = null;
725         $browser = get_file_browser();
727         // Call the files api to create a file.
728         $draftfile = core_files_external::upload($contextid, $component, $filearea, $itemid, $filepath,
729                                                  $filename, $filecontent, $contextlevel, $instanceid);
730         $draftfile = external_api::clean_returnvalue(core_files_external::upload_returns(), $draftfile);
732         $draftid = $draftfile['itemid'];
733         // Make sure the file was created.
734         $file = $browser->get_file_info($context, $component, $filearea, $draftid, $filepath, $filename);
735         $this->assertNotEmpty($file);
737         // Make sure the file does not exist in the user private files.
738         $file = $browser->get_file_info($context, $component, 'private', 0, $filepath, $filename);
739         $this->assertEmpty($file);
741         // Call the external function.
742         core_user_external::add_user_private_files($draftid);
744         // Make sure the file was added to the user private files.
745         $file = $browser->get_file_info($context, $component, 'private', 0, $filepath, $filename);
746         $this->assertNotEmpty($file);
747     }
749     /**
750      * Test add user device
751      */
752     public function test_add_user_device() {
753         global $USER, $CFG, $DB;
755         $this->resetAfterTest(true);
757         $device = array(
758                 'appid' => 'com.moodle.moodlemobile',
759                 'name' => 'occam',
760                 'model' => 'Nexus 4',
761                 'platform' => 'Android',
762                 'version' => '4.2.2',
763                 'pushid' => 'apushdkasdfj4835',
764                 'uuid' => 'asdnfl348qlksfaasef859'
765                 );
767         // Call the external function.
768         core_user_external::add_user_device($device['appid'], $device['name'], $device['model'], $device['platform'],
769                                             $device['version'], $device['pushid'], $device['uuid']);
771         $created = $DB->get_record('user_devices', array('pushid' => $device['pushid']));
772         $created = (array) $created;
774         $this->assertEquals($device, array_intersect_key((array)$created, $device));
776         // Test reuse the same pushid value.
777         $warnings = core_user_external::add_user_device($device['appid'], $device['name'], $device['model'], $device['platform'],
778                                                         $device['version'], $device['pushid'], $device['uuid']);
779         // We need to execute the return values cleaning process to simulate the web service server.
780         $warnings = external_api::clean_returnvalue(core_user_external::add_user_device_returns(), $warnings);
781         $this->assertCount(1, $warnings);
783         // Test update an existing device.
784         $device['pushid'] = 'different than before';
785         $warnings = core_user_external::add_user_device($device['appid'], $device['name'], $device['model'], $device['platform'],
786                                                         $device['version'], $device['pushid'], $device['uuid']);
787         $warnings = external_api::clean_returnvalue(core_user_external::add_user_device_returns(), $warnings);
789         $this->assertEquals(1, $DB->count_records('user_devices'));
790         $updated = $DB->get_record('user_devices', array('pushid' => $device['pushid']));
791         $this->assertEquals($device, array_intersect_key((array)$updated, $device));
793         // Test creating a new device just changing the uuid.
794         $device['uuid'] = 'newuidforthesameuser';
795         $device['pushid'] = 'new different than before';
796         $warnings = core_user_external::add_user_device($device['appid'], $device['name'], $device['model'], $device['platform'],
797                                                         $device['version'], $device['pushid'], $device['uuid']);
798         $warnings = external_api::clean_returnvalue(core_user_external::add_user_device_returns(), $warnings);
799         $this->assertEquals(2, $DB->count_records('user_devices'));
800     }
802     /**
803      * Test remove user device
804      */
805     public function test_remove_user_device() {
806         global $USER, $CFG, $DB;
808         $this->resetAfterTest(true);
810         $device = array(
811                 'appid' => 'com.moodle.moodlemobile',
812                 'name' => 'occam',
813                 'model' => 'Nexus 4',
814                 'platform' => 'Android',
815                 'version' => '4.2.2',
816                 'pushid' => 'apushdkasdfj4835',
817                 'uuid' => 'ABCDE3723ksdfhasfaasef859'
818                 );
820         // A device with the same properties except the appid and pushid.
821         $device2 = $device;
822         $device2['pushid'] = "0987654321";
823         $device2['appid'] = "other.app.com";
825         // Create a user device using the external API function.
826         core_user_external::add_user_device($device['appid'], $device['name'], $device['model'], $device['platform'],
827                                             $device['version'], $device['pushid'], $device['uuid']);
829         // Create the same device but for a different app.
830         core_user_external::add_user_device($device2['appid'], $device2['name'], $device2['model'], $device2['platform'],
831                                             $device2['version'], $device2['pushid'], $device2['uuid']);
833         // Try to remove a device that does not exist.
834         $result = core_user_external::remove_user_device('1234567890');
835         $result = external_api::clean_returnvalue(core_user_external::remove_user_device_returns(), $result);
836         $this->assertFalse($result['removed']);
837         $this->assertCount(1, $result['warnings']);
839         // Try to remove a device that does not exist for an existing app.
840         $result = core_user_external::remove_user_device('1234567890', $device['appid']);
841         $result = external_api::clean_returnvalue(core_user_external::remove_user_device_returns(), $result);
842         $this->assertFalse($result['removed']);
843         $this->assertCount(1, $result['warnings']);
845         // Remove an existing device for an existing app. This will remove one of the two devices.
846         $result = core_user_external::remove_user_device($device['uuid'], $device['appid']);
847         $result = external_api::clean_returnvalue(core_user_external::remove_user_device_returns(), $result);
848         $this->assertTrue($result['removed']);
850         // Remove all the devices. This must remove the remaining device.
851         $result = core_user_external::remove_user_device($device['uuid']);
852         $result = external_api::clean_returnvalue(core_user_external::remove_user_device_returns(), $result);
853         $this->assertTrue($result['removed']);
854     }