Merge branch 'MDL-60570-master' of git://github.com/andrewnicols/moodle
[moodle.git] / admin / tool / mobile / 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  * Moodle Mobile admin tool external functions tests.
19  *
20  * @package    tool_mobile
21  * @category   external
22  * @copyright  2016 Juan Leyva
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  * @since      Moodle 3.1
25  */
27 defined('MOODLE_INTERNAL') || die();
29 global $CFG;
31 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
33 use tool_mobile\external;
34 use tool_mobile\api;
36 /**
37  * Moodle Mobile admin tool external functions tests.
38  *
39  * @package     tool_mobile
40  * @copyright   2016 Juan Leyva
41  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42  * @since       Moodle 3.1
43  */
44 class tool_mobile_external_testcase extends externallib_advanced_testcase {
46     /**
47      * Test get_plugins_supporting_mobile.
48      * This is a very basic test because currently there aren't plugins supporting Mobile in core.
49      */
50     public function test_get_plugins_supporting_mobile() {
51         $result = external::get_plugins_supporting_mobile();
52         $result = external_api::clean_returnvalue(external::get_plugins_supporting_mobile_returns(), $result);
53         $this->assertCount(0, $result['warnings']);
54         $this->assertArrayHasKey('plugins', $result);
55         $this->assertTrue(is_array($result['plugins']));
56     }
58     public function test_get_public_config() {
59         global $CFG, $SITE, $OUTPUT;
61         $this->resetAfterTest(true);
62         $result = external::get_public_config();
63         $result = external_api::clean_returnvalue(external::get_public_config_returns(), $result);
65         // Test default values.
66         $context = context_system::instance();
67         list($authinstructions, $notusedformat) = external_format_text($CFG->auth_instructions, FORMAT_MOODLE, $context->id);
68         list($maintenancemessage, $notusedformat) = external_format_text($CFG->maintenance_message, FORMAT_MOODLE, $context->id);
70         $expected = array(
71             'wwwroot' => $CFG->wwwroot,
72             'httpswwwroot' => $CFG->httpswwwroot,
73             'sitename' => external_format_string($SITE->fullname, $context->id, true),
74             'guestlogin' => $CFG->guestloginbutton,
75             'rememberusername' => $CFG->rememberusername,
76             'authloginviaemail' => $CFG->authloginviaemail,
77             'registerauth' => $CFG->registerauth,
78             'forgottenpasswordurl' => $CFG->forgottenpasswordurl,
79             'authinstructions' => $authinstructions,
80             'authnoneenabled' => (int) is_enabled_auth('none'),
81             'enablewebservices' => $CFG->enablewebservices,
82             'enablemobilewebservice' => $CFG->enablemobilewebservice,
83             'maintenanceenabled' => $CFG->maintenance_enabled,
84             'maintenancemessage' => $maintenancemessage,
85             'typeoflogin' => api::LOGIN_VIA_APP,
86             'mobilecssurl' => '',
87             'tool_mobile_disabledfeatures' => '',
88             'launchurl' => "$CFG->wwwroot/$CFG->admin/tool/mobile/launch.php",
89             'warnings' => array()
90         );
91         $this->assertEquals($expected, $result);
93         // Change some values.
94         set_config('registerauth', 'email');
95         $authinstructions = 'Something with <b>html tags</b>';
96         set_config('auth_instructions', $authinstructions);
97         set_config('typeoflogin', api::LOGIN_VIA_BROWSER, 'tool_mobile');
98         set_config('logo', 'mock.png', 'core_admin');
99         set_config('logocompact', 'mock.png', 'core_admin');
100         set_config('forgottenpasswordurl', 'mailto:fake@email.zy'); // Test old hack.
102         list($authinstructions, $notusedformat) = external_format_text($authinstructions, FORMAT_MOODLE, $context->id);
103         $expected['registerauth'] = 'email';
104         $expected['authinstructions'] = $authinstructions;
105         $expected['typeoflogin'] = api::LOGIN_VIA_BROWSER;
106         $expected['forgottenpasswordurl'] = ''; // Expect empty when it's not an URL.
108         if ($logourl = $OUTPUT->get_logo_url()) {
109             $expected['logourl'] = $logourl->out(false);
110         }
111         if ($compactlogourl = $OUTPUT->get_compact_logo_url()) {
112             $expected['compactlogourl'] = $compactlogourl->out(false);
113         }
115         $result = external::get_public_config();
116         $result = external_api::clean_returnvalue(external::get_public_config_returns(), $result);
117         $this->assertEquals($expected, $result);
118     }
120     /**
121      * Test get_config
122      */
123     public function test_get_config() {
124         global $CFG, $SITE;
125         require_once($CFG->dirroot . '/course/format/lib.php');
127         $this->resetAfterTest(true);
129         $mysitepolicy = 'http://mysite.is/policy/';
130         set_config('sitepolicy', $mysitepolicy);
132         $result = external::get_config();
133         $result = external_api::clean_returnvalue(external::get_config_returns(), $result);
135         // SITE summary is null in phpunit which gets transformed to an empty string by format_text.
136         list($sitesummary, $unused) = external_format_text($SITE->summary, $SITE->summaryformat, context_system::instance()->id);
138         // Test default values.
139         $context = context_system::instance();
140         $expected = array(
141             array('name' => 'fullname', 'value' => $SITE->fullname),
142             array('name' => 'shortname', 'value' => $SITE->shortname),
143             array('name' => 'summary', 'value' => $sitesummary),
144             array('name' => 'summaryformat', 'value' => FORMAT_HTML),
145             array('name' => 'frontpage', 'value' => $CFG->frontpage),
146             array('name' => 'frontpageloggedin', 'value' => $CFG->frontpageloggedin),
147             array('name' => 'maxcategorydepth', 'value' => $CFG->maxcategorydepth),
148             array('name' => 'frontpagecourselimit', 'value' => $CFG->frontpagecourselimit),
149             array('name' => 'numsections', 'value' => course_get_format($SITE)->get_last_section_number()),
150             array('name' => 'newsitems', 'value' => $SITE->newsitems),
151             array('name' => 'commentsperpage', 'value' => $CFG->commentsperpage),
152             array('name' => 'sitepolicy', 'value' => $mysitepolicy),
153             array('name' => 'disableuserimages', 'value' => $CFG->disableuserimages),
154             array('name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false)),
155             array('name' => 'tool_mobile_forcelogout', 'value' => 0),
156             array('name' => 'tool_mobile_customlangstrings', 'value' => ''),
157             array('name' => 'tool_mobile_disabledfeatures', 'value' => ''),
158             array('name' => 'tool_mobile_custommenuitems', 'value' => ''),
159         );
160         $this->assertCount(0, $result['warnings']);
161         $this->assertEquals($expected, $result['settings']);
163         // Change a value and retrieve filtering by section.
164         set_config('commentsperpage', 1);
165         $expected[10]['value'] = 1;
166         // Remove not expected elements.
167         array_splice($expected, 11);
169         $result = external::get_config('frontpagesettings');
170         $result = external_api::clean_returnvalue(external::get_config_returns(), $result);
171         $this->assertCount(0, $result['warnings']);
172         $this->assertEquals($expected, $result['settings']);
173     }
175     /*
176      * Test get_autologin_key.
177      */
178     public function test_get_autologin_key() {
179         global $DB, $CFG, $USER;
181         $this->resetAfterTest(true);
183         $user = $this->getDataGenerator()->create_user();
184         $this->setUser($user);
185         $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE));
187         $token = external_generate_token_for_current_user($service);
189         // Check we got the private token.
190         $this->assertTrue(isset($token->privatetoken));
192         // Enable requeriments.
193         $_GET['wstoken'] = $token->token;   // Mock parameters.
195         // Even if we force the password change for the current user we should be able to retrieve the key.
196         set_user_preference('auth_forcepasswordchange', 1, $user->id);
198         $this->setCurrentTimeStart();
199         $result = external::get_autologin_key($token->privatetoken);
200         $result = external_api::clean_returnvalue(external::get_autologin_key_returns(), $result);
201         // Validate the key.
202         $this->assertEquals(32, core_text::strlen($result['key']));
203         $key = $DB->get_record('user_private_key', array('value' => $result['key']));
204         $this->assertEquals($USER->id, $key->userid);
205         $this->assertTimeCurrent($key->validuntil - api::LOGIN_KEY_TTL);
207         // Now, try with an invalid private token.
208         set_user_preference('tool_mobile_autologin_request_last', time() - HOURSECS, $USER);
210         $this->expectException('moodle_exception');
211         $this->expectExceptionMessage(get_string('invalidprivatetoken', 'tool_mobile'));
212         $result = external::get_autologin_key(random_string('64'));
213     }
215     /**
216      * Test get_autologin_key missing ws.
217      */
218     public function test_get_autologin_key_missing_ws() {
219         global $CFG;
220         $this->resetAfterTest(true);
222         // Need to disable webservices to verify that's checked.
223         $CFG->enablewebservices = 0;
224         $CFG->enablemobilewebservice = 0;
226         $this->setAdminUser();
227         $this->expectException('moodle_exception');
228         $this->expectExceptionMessage(get_string('enablewsdescription', 'webservice'));
229         $result = external::get_autologin_key('');
230     }
232     /**
233      * Test get_autologin_key missing https.
234      */
235     public function test_get_autologin_key_missing_https() {
236         global $CFG;
238         // Need to simulate a non HTTPS site here.
239         $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot);
241         $this->resetAfterTest(true);
242         $this->setAdminUser();
244         $this->expectException('moodle_exception');
245         $this->expectExceptionMessage(get_string('httpsrequired', 'tool_mobile'));
246         $result = external::get_autologin_key('');
247     }
249     /**
250      * Test get_autologin_key missing admin.
251      */
252     public function test_get_autologin_key_missing_admin() {
253         global $CFG;
255         $this->resetAfterTest(true);
256         $this->setAdminUser();
258         $this->expectException('moodle_exception');
259         $this->expectExceptionMessage(get_string('autologinnotallowedtoadmins', 'tool_mobile'));
260         $result = external::get_autologin_key('');
261     }
263     /**
264      * Test get_autologin_key locked.
265      */
266     public function test_get_autologin_key_missing_locked() {
267         global $CFG, $DB, $USER;
269         $this->resetAfterTest(true);
270         $user = $this->getDataGenerator()->create_user();
271         $this->setUser($user);
273         $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE));
275         $token = external_generate_token_for_current_user($service);
276         $_GET['wstoken'] = $token->token;   // Mock parameters.
278         $result = external::get_autologin_key($token->privatetoken);
279         $result = external_api::clean_returnvalue(external::get_autologin_key_returns(), $result);
281         // Mock last time request.
282         $mocktime = time() - 7 * MINSECS;
283         set_user_preference('tool_mobile_autologin_request_last', $mocktime, $USER);
284         $result = external::get_autologin_key($token->privatetoken);
285         $result = external_api::clean_returnvalue(external::get_autologin_key_returns(), $result);
287         // We just requested one token, we must wait.
288         $this->expectException('moodle_exception');
289         $this->expectExceptionMessage(get_string('autologinkeygenerationlockout', 'tool_mobile'));
290         $result = external::get_autologin_key($token->privatetoken);
291     }