on-demand release 4.0beta+
[moodle.git] / login / tests / login_notifications_test.php
blobeecd58f52e23dc81dc4c97e5e9a3ad84f8d8c964
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.
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 namespace core;
19 defined('MOODLE_INTERNAL') || die();
21 global $CFG;
22 require_once($CFG->dirroot . '/lib/externallib.php');
24 /**
25 * Contains tests for course related notifications.
27 * @package core
28 * @copyright 2021 Juan Leyva <juan@moodle.com>
29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31 class login_notifications_test extends \advanced_testcase {
33 /**
34 * Load required classes
36 public static function setUpBeforeClass(): void {
37 global $CFG;
39 require_once($CFG->libdir . '/externallib.php');
42 /**
43 * Test new login notification.
45 public function test_login_notification() {
46 global $SESSION;
48 $this->resetAfterTest();
50 $loginuser = self::getDataGenerator()->create_user();
51 $this->setUser(0);
53 // Mock data for test.
54 $loginuser->lastip = '1.2.3.4.6'; // Different ip that current.
55 $SESSION->isnewsessioncookie = true; // New session cookie.
56 @complete_user_login($loginuser);
58 // Redirect messages to sink and stop buffer output from CLI task.
59 $sink = $this->redirectMessages();
60 ob_start();
61 $this->runAdhocTasks('\core\task\send_login_notifications');
62 $output = ob_get_contents();
63 ob_end_clean();
64 $messages = $sink->get_messages();
65 $sink->close();
67 // Send notification, new IP and new session.
68 $this->assertCount(1, $messages);
69 $this->assertEquals($loginuser->id, $messages[0]->useridto);
70 $this->assertEquals('newlogin', $messages[0]->eventtype);
73 /**
74 * Test new login notification is skipped because of same IP from last login.
76 public function test_login_notification_skip_same_ip() {
77 global $SESSION;
79 $this->resetAfterTest();
81 $loginuser = self::getDataGenerator()->create_user();
82 $this->setUser(0);
84 // Mock data for test.
85 $SESSION->isnewsessioncookie = true; // New session cookie.
86 @complete_user_login($loginuser);
88 // Redirect messages to sink and stop buffer output from CLI task.
89 $sink = $this->redirectMessages();
90 ob_start();
91 $this->runAdhocTasks('\core\task\send_login_notifications');
92 $output = ob_get_contents();
93 ob_end_clean();
94 $messages = $sink->get_messages();
95 $sink->close();
97 // Skip notification when we have the same previous IP even if the browser used to connect is new.
98 $this->assertCount(0, $messages);
102 * Test new login notification is skipped because of same browser from last login.
104 public function test_login_notification_skip_same_browser() {
105 global $SESSION;
107 $this->resetAfterTest();
109 $loginuser = self::getDataGenerator()->create_user();
110 $this->setUser(0);
112 // Mock data for test.
113 $loginuser->lastip = '1.2.3.4.6'; // Different ip that current.
114 $SESSION->isnewsessioncookie = false;
115 @complete_user_login($loginuser);
117 // Redirect messages to sink and stop buffer output from CLI task.
118 $sink = $this->redirectMessages();
119 ob_start();
120 $this->runAdhocTasks('\core\task\send_login_notifications');
121 $output = ob_get_contents();
122 ob_end_clean();
123 $messages = $sink->get_messages();
124 $sink->close();
126 // Skip notification, different ip but same browser (probably, mobile phone browser).
127 $this->assertCount(0, $messages);
131 * Test new login notification is skipped because of auto-login from the mobile app (skip duplicated notifications).
133 public function test_login_notification_skip_mobileapp() {
134 global $SESSION;
136 $this->resetAfterTest();
138 $loginuser = self::getDataGenerator()->create_user();
139 $this->setUser(0);
141 // Mock data for test.
142 $loginuser->lastip = '1.2.3.4.6'; // Different ip that current.
143 $SESSION->isnewsessioncookie = true; // New session cookie.
144 \core_useragent::instance(true, 'MoodleMobile'); // Force fake mobile app user agent.
145 @complete_user_login($loginuser);
147 // Redirect messages to sink and stop buffer output from CLI task.
148 $sink = $this->redirectMessages();
149 ob_start();
150 $this->runAdhocTasks('\core\task\send_login_notifications');
151 $output = ob_get_contents();
152 ob_end_clean();
153 $messages = $sink->get_messages();
154 $sink->close();
156 $this->assertCount(0, $messages);
160 * Test new mobile app login notification.
162 public function test_mobile_app_login_notification() {
163 global $USER, $DB, $SESSION;
165 $this->resetAfterTest();
167 $loginuser = self::getDataGenerator()->create_user();
168 $this->setUser($loginuser);
170 // Mock data for test.
171 $USER->lastip = '1.2.3.4.6'; // Different ip that current.
173 $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE));
174 $token = external_generate_token_for_current_user($service);
175 \core_useragent::instance(true, 'MoodleMobile'); // Force fake mobile app user agent.
177 // Simulate we are using an new device.
178 $fakedevice = (object) [
179 'userid' => $USER->id,
180 'appid' => 'com.moodle.moodlemobile',
181 'name' => 'occam',
182 'model' => 'Nexus 4',
183 'platform' => 'Android',
184 'version' => '4.2.2',
185 'pushid' => 'kishUhd',
186 'uuid' => 'KIhud7s',
187 'timecreated' => time() + MINSECS,
188 'timemodified' => time() + MINSECS
190 $DB->insert_record('user_devices', $fakedevice);
192 external_log_token_request($token);
194 // Redirect messages to sink and stop buffer output from CLI task.
195 $sink = $this->redirectMessages();
196 ob_start();
197 $this->runAdhocTasks('\core\task\send_login_notifications');
198 $output = ob_get_contents();
199 ob_end_clean();
200 $messages = $sink->get_messages();
201 $sink->close();
203 // We sent a login notification because we are using a new device and different IP.
204 $this->assertCount(1, $messages);
205 $this->assertEquals($loginuser->id, $messages[0]->useridto);
206 $this->assertEquals('newlogin', $messages[0]->eventtype);
210 * Test new mobile app login notification skipped becase of same last ip.
212 public function test_mobile_app_login_notification_skip_same_ip() {
213 global $USER, $DB, $SESSION;
215 $this->resetAfterTest();
217 $loginuser = self::getDataGenerator()->create_user();
218 $this->setUser($loginuser);
220 // Mock data for test.
221 $USER->lastip = '0.0.0.0';
222 $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE));
223 $token = external_generate_token_for_current_user($service);
224 \core_useragent::instance(true, 'MoodleMobile'); // Force fake mobile app user agent.
226 // Simulate we are using an new device.
227 $fakedevice = (object) [
228 'userid' => $USER->id,
229 'appid' => 'com.moodle.moodlemobile',
230 'name' => 'occam',
231 'model' => 'Nexus 4',
232 'platform' => 'Android',
233 'version' => '4.2.2',
234 'pushid' => 'kishUhd',
235 'uuid' => 'KIhud7s',
236 'timecreated' => time() + MINSECS,
237 'timemodified' => time() + MINSECS
239 $DB->insert_record('user_devices', $fakedevice);
241 external_log_token_request($token);
243 // Redirect messages to sink and stop buffer output from CLI task.
244 $sink = $this->redirectMessages();
245 ob_start();
246 $this->runAdhocTasks('\core\task\send_login_notifications');
247 $output = ob_get_contents();
248 ob_end_clean();
249 $messages = $sink->get_messages();
250 $sink->close();
252 // While using the same IP avoid sending new login notifications even if we are using a new device.
253 $this->assertCount(0, $messages);
257 * Test new mobile app login notification skipped becase of same device.
259 public function test_mobile_app_login_notification_skip_same_device() {
260 global $USER, $DB, $SESSION;
262 $this->resetAfterTest();
264 $loginuser = self::getDataGenerator()->create_user();
265 $this->setUser($loginuser);
267 // Mock data for test.
268 $USER->lastip = '1.2.3.4.6'; // New ip.
269 $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE));
270 $token = external_generate_token_for_current_user($service);
271 \core_useragent::instance(true, 'MoodleMobile'); // Force fake mobile app user agent.
273 external_log_token_request($token);
275 // Redirect messages to sink and stop buffer output from CLI task.
276 $sink = $this->redirectMessages();
277 ob_start();
278 $this->runAdhocTasks('\core\task\send_login_notifications');
279 $output = ob_get_contents();
280 ob_end_clean();
281 $messages = $sink->get_messages();
282 $sink->close();
284 // While using the same device avoid sending new login notifications even if the IP changes.
285 $this->assertCount(0, $messages);