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/>. 16 17 /** 18 * Data provider tests. 19 * 20 * @package mod_chat 21 * @category test 22 * @copyright 2018 Frédéric Massart 23 * @author Frédéric Massart <fred@branchup.tech> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 namespace mod_chat\privacy; 27 28 defined('MOODLE_INTERNAL') || die(); 29 global $CFG; 30 31 use core_privacy\tests\provider_testcase; 32 use core_privacy\local\request\approved_contextlist; 33 use core_privacy\local\request\approved_userlist; 34 use core_privacy\local\request\transform; 35 use core_privacy\local\request\writer; 36 use mod_chat\privacy\provider; 37 38 require_once($CFG->dirroot . '/mod/chat/lib.php'); 39 40 /** 41 * Data provider testcase class. 42 * 43 * @package mod_chat 44 * @category test 45 * @copyright 2018 Frédéric Massart 46 * @author Frédéric Massart <fred@branchup.tech> 47 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 48 */ 49 class provider_test extends provider_testcase { 50 51 public function setUp(): void { 52 global $PAGE; 53 $this->resetAfterTest(); 54 $PAGE->get_renderer('core'); 55 } 56 57 public function test_get_contexts_for_userid() { 58 global $DB; 59 $dg = $this->getDataGenerator(); 60 $c1 = $dg->create_course(); 61 $c2 = $dg->create_course(); 62 63 $u1 = $dg->create_user(); 64 $u2 = $dg->create_user(); 65 66 $chat1a = $dg->create_module('chat', ['course' => $c1]); 67 $chat1b = $dg->create_module('chat', ['course' => $c1]); 68 $chat2a = $dg->create_module('chat', ['course' => $c2]); 69 70 // Logins but no message. 71 $chatuser = $this->login_user_in_course_chat($u1, $c1, $chat1a); 72 73 // Logins and messages. 74 $chatuser = $this->login_user_in_course_chat($u1, $c1, $chat1b); 75 chat_send_chatmessage($chatuser, 'Hello world!'); 76 77 // Silent login (no system message). 78 $chatuser = $this->login_user_in_course_chat($u1, $c2, $chat2a, 0, true); 79 80 // Silent login and messages. 81 $chatuser = $this->login_user_in_course_chat($u2, $c1, $chat1b, 0, true); 82 chat_send_chatmessage($chatuser, 'Ça va ?'); 83 chat_send_chatmessage($chatuser, 'Moi, ça va.'); 84 85 // Silent login and messages. 86 $chatuser = $this->login_user_in_course_chat($u2, $c2, $chat2a); 87 chat_send_chatmessage($chatuser, 'What\'s happening here?'); 88 89 // Check contexts for user 1. 90 $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids(); 91 $this->assertCount(2, $contextids); 92 $this->assertTrue(in_array(\context_module::instance($chat1a->cmid)->id, $contextids)); 93 $this->assertTrue(in_array(\context_module::instance($chat1b->cmid)->id, $contextids)); 94 95 $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids(); 96 $this->assertCount(2, $contextids); 97 $this->assertTrue(in_array(\context_module::instance($chat1b->cmid)->id, $contextids)); 98 $this->assertTrue(in_array(\context_module::instance($chat2a->cmid)->id, $contextids)); 99 } 100 101 /** 102 * Test that only users with relevant contexts are fetched. 103 */ 104 public function test_get_users_in_context() { 105 $component = 'mod_chat'; 106 $dg = $this->getDataGenerator(); 107 $c1 = $dg->create_course(); 108 $c2 = $dg->create_course(); 109 110 $u1 = $dg->create_user(); 111 $u2 = $dg->create_user(); 112 113 $chat1a = $dg->create_module('chat', ['course' => $c1]); 114 $chat1b = $dg->create_module('chat', ['course' => $c1]); 115 $chat2a = $dg->create_module('chat', ['course' => $c2]); 116 117 // Logins but no message. 118 $chatuser = $this->login_user_in_course_chat($u1, $c1, $chat1a); 119 120 // Logins and messages. 121 $chatuser = $this->login_user_in_course_chat($u1, $c1, $chat1b); 122 chat_send_chatmessage($chatuser, 'Hello world!'); 123 124 // Silent login (no system message). 125 $chatuser = $this->login_user_in_course_chat($u1, $c2, $chat2a, 0, true); 126 127 // Silent login and messages. 128 $chatuser = $this->login_user_in_course_chat($u2, $c1, $chat1b, 0, true); 129 chat_send_chatmessage($chatuser, 'Ça va ?'); 130 chat_send_chatmessage($chatuser, 'Moi, ça va.'); 131 132 // Silent login and messages. 133 $chatuser = $this->login_user_in_course_chat($u2, $c2, $chat2a); 134 chat_send_chatmessage($chatuser, 'What\'s happening here?'); 135 136 $context1a = \context_module::instance($chat1a->cmid); 137 $context1b = \context_module::instance($chat1b->cmid); 138 $context2a = \context_module::instance($chat2a->cmid); 139 140 $userlist1a = new \core_privacy\local\request\userlist($context1a, $component); 141 $userlist1b = new \core_privacy\local\request\userlist($context1b, $component); 142 $userlist2a = new \core_privacy\local\request\userlist($context2a, $component); 143 \mod_chat\privacy\provider::get_users_in_context($userlist1a); 144 \mod_chat\privacy\provider::get_users_in_context($userlist1b); 145 \mod_chat\privacy\provider::get_users_in_context($userlist2a); 146 147 // Ensure correct users are found in relevant contexts. 148 $this->assertCount(1, $userlist1a); 149 $expected = [$u1->id]; 150 $actual = $userlist1a->get_userids(); 151 $this->assertEquals($expected, $actual); 152 153 $this->assertCount(2, $userlist1b); 154 $expected = [$u1->id, $u2->id]; 155 $actual = $userlist1b->get_userids(); 156 sort($expected); 157 sort($actual); 158 $this->assertEquals($expected, $actual); 159 160 $this->assertCount(1, $userlist2a); 161 $expected = [$u1->id]; 162 $actual = $userlist1a->get_userids(); 163 $this->assertEquals($expected, $actual); 164 } 165 166 public function test_delete_data_for_all_users_in_context() { 167 global $DB; 168 $dg = $this->getDataGenerator(); 169 $c1 = $dg->create_course(); 170 171 $u1 = $dg->create_user(); 172 $u2 = $dg->create_user(); 173 174 $chat1a = $dg->create_module('chat', ['course' => $c1]); 175 $chat1b = $dg->create_module('chat', ['course' => $c1]); 176 $chat1actx = \context_module::instance($chat1a->cmid); 177 $chat1bctx = \context_module::instance($chat1b->cmid); 178 179 $u1chat1a = $this->login_user_in_course_chat($u1, $c1, $chat1a); 180 $u2chat1a = $this->login_user_in_course_chat($u2, $c1, $chat1a); 181 chat_send_chatmessage($u1chat1a, 'Ça va ?'); 182 chat_send_chatmessage($u2chat1a, 'Oui, et toi ?'); 183 chat_send_chatmessage($u1chat1a, 'Bien merci.'); 184 chat_send_chatmessage($u2chat1a, 'Pourquoi ils disent omelette "du" fromage ?!'); 185 chat_send_chatmessage($u1chat1a, 'Aucune idée'); 186 $this->assert_has_data_in_chat($u1, $chat1a); 187 $this->assert_has_data_in_chat($u2, $chat1a); 188 189 $u1chat1b = $this->login_user_in_course_chat($u1, $c1, $chat1b); 190 $u2chat1b = $this->login_user_in_course_chat($u2, $c1, $chat1b); 191 chat_send_chatmessage($u1chat1b, 'How are you going?'); 192 chat_send_chatmessage($u2chat1b, 'Alright, you?'); 193 chat_send_chatmessage($u1chat1b, 'Good, thanks.'); 194 chat_send_chatmessage($u2chat1b, 'Sacre bleu!'); 195 chat_send_chatmessage($u1chat1b, '\ö/'); 196 $this->assert_has_data_in_chat($u1, $chat1b); 197 $this->assert_has_data_in_chat($u2, $chat1b); 198 199 // No change. 200 provider::delete_data_for_all_users_in_context(\context_course::instance($c1->id)); 201 $this->assert_has_data_in_chat($u1, $chat1a); 202 $this->assert_has_data_in_chat($u2, $chat1a); 203 $this->assert_has_data_in_chat($u1, $chat1b); 204 $this->assert_has_data_in_chat($u2, $chat1b); 205 206 // Deletinge first chat does not affect other chat. 207 provider::delete_data_for_all_users_in_context($chat1actx); 208 $this->assert_has_no_data_in_chat($u1, $chat1a); 209 $this->assert_has_no_data_in_chat($u2, $chat1a); 210 $this->assert_has_data_in_chat($u1, $chat1b); 211 $this->assert_has_data_in_chat($u2, $chat1b); 212 } 213 214 public function test_delete_data_for_user() { 215 global $DB; 216 $dg = $this->getDataGenerator(); 217 $c1 = $dg->create_course(); 218 219 $u1 = $dg->create_user(); 220 $u2 = $dg->create_user(); 221 222 $chat1a = $dg->create_module('chat', ['course' => $c1]); 223 $chat1b = $dg->create_module('chat', ['course' => $c1]); 224 $chat1actx = \context_module::instance($chat1a->cmid); 225 $chat1bctx = \context_module::instance($chat1b->cmid); 226 227 $u1chat1a = $this->login_user_in_course_chat($u1, $c1, $chat1a); 228 $u2chat1a = $this->login_user_in_course_chat($u2, $c1, $chat1a); 229 chat_send_chatmessage($u1chat1a, 'Ça va ?'); 230 chat_send_chatmessage($u2chat1a, 'Oui, et toi ?'); 231 chat_send_chatmessage($u1chat1a, 'Bien merci.'); 232 chat_send_chatmessage($u2chat1a, 'Pourquoi ils disent omelette "du" fromage ?!'); 233 chat_send_chatmessage($u1chat1a, 'Aucune idée'); 234 $this->assert_has_data_in_chat($u1, $chat1a); 235 $this->assert_has_data_in_chat($u2, $chat1a); 236 237 $u1chat1b = $this->login_user_in_course_chat($u1, $c1, $chat1b); 238 $u2chat1b = $this->login_user_in_course_chat($u2, $c1, $chat1b); 239 chat_send_chatmessage($u1chat1b, 'How are you going?'); 240 chat_send_chatmessage($u2chat1b, 'Alright, you?'); 241 chat_send_chatmessage($u1chat1b, 'Good, thanks.'); 242 chat_send_chatmessage($u2chat1b, 'Sacre bleu!'); 243 chat_send_chatmessage($u1chat1b, '\ö/'); 244 $this->assert_has_data_in_chat($u1, $chat1b); 245 $this->assert_has_data_in_chat($u2, $chat1b); 246 247 provider::delete_data_for_user(new approved_contextlist($u1, 'mod_chat', [$chat1actx->id])); 248 $this->assert_has_no_data_in_chat($u1, $chat1a); 249 $this->assert_has_data_in_chat($u2, $chat1a); 250 $this->assert_has_data_in_chat($u1, $chat1b); 251 $this->assert_has_data_in_chat($u2, $chat1b); 252 253 provider::delete_data_for_user(new approved_contextlist($u2, 'mod_chat', [$chat1actx->id, $chat1bctx->id])); 254 $this->assert_has_no_data_in_chat($u1, $chat1a); 255 $this->assert_has_no_data_in_chat($u2, $chat1a); 256 $this->assert_has_data_in_chat($u1, $chat1b); 257 $this->assert_has_no_data_in_chat($u2, $chat1b); 258 } 259 260 /** 261 * Test that data for users in approved userlist is deleted. 262 */ 263 public function test_delete_data_for_users() { 264 global $DB; 265 $component = 'mod_chat'; 266 $dg = $this->getDataGenerator(); 267 $c1 = $dg->create_course(); 268 269 $u1 = $dg->create_user(); 270 $u2 = $dg->create_user(); 271 $u3 = $dg->create_user(); 272 273 $chat1 = $dg->create_module('chat', ['course' => $c1]); 274 $chat1context = \context_module::instance($chat1->cmid); 275 276 $u1chat1 = $this->login_user_in_course_chat($u1, $c1, $chat1); 277 $u2chat1 = $this->login_user_in_course_chat($u2, $c1, $chat1); 278 $u3chat1 = $this->login_user_in_course_chat($u3, $c1, $chat1); 279 chat_send_chatmessage($u1chat1, 'Ça va ?'); 280 chat_send_chatmessage($u2chat1, 'Oui, et toi ?'); 281 chat_send_chatmessage($u1chat1, 'Bien merci.'); 282 chat_send_chatmessage($u2chat1, 'Pourquoi ils disent omelette "du" fromage ?!'); 283 chat_send_chatmessage($u1chat1, 'Aucune idée'); 284 chat_send_chatmessage($u3chat1, 'Je ne comprends pas'); 285 $this->assert_has_data_in_chat($u1, $chat1); 286 $this->assert_has_data_in_chat($u2, $chat1); 287 $this->assert_has_data_in_chat($u3, $chat1); 288 289 $chat2 = $dg->create_module('chat', ['course' => $c1]); 290 291 $u1chat2 = $this->login_user_in_course_chat($u1, $c1, $chat2); 292 $u2chat2 = $this->login_user_in_course_chat($u2, $c1, $chat2); 293 $u3chat2 = $this->login_user_in_course_chat($u3, $c1, $chat2); 294 chat_send_chatmessage($u1chat2, 'Why do we have a separate chat?'); 295 chat_send_chatmessage($u2chat2, 'I have no idea!'); 296 chat_send_chatmessage($u3chat2, 'Me either.'); 297 $this->assert_has_data_in_chat($u1, $chat2); 298 $this->assert_has_data_in_chat($u2, $chat2); 299 $this->assert_has_data_in_chat($u3, $chat2); 300 301 // Delete user 1 and 2 data from chat 1 context only. 302 $approveduserids = [$u1->id, $u2->id]; 303 $approvedlist = new approved_userlist($chat1context, $component, $approveduserids); 304 provider::delete_data_for_users($approvedlist); 305 306 // Ensure correct chat data is deleted. 307 $this->assert_has_no_data_in_chat($u1, $chat1); 308 $this->assert_has_no_data_in_chat($u2, $chat1); 309 $this->assert_has_data_in_chat($u3, $chat1); 310 311 $this->assert_has_data_in_chat($u1, $chat2); 312 $this->assert_has_data_in_chat($u2, $chat2); 313 $this->assert_has_data_in_chat($u3, $chat2); 314 } 315 316 public function test_export_data_for_user() { 317 global $DB; 318 $dg = $this->getDataGenerator(); 319 $c1 = $dg->create_course(); 320 321 $u1 = $dg->create_user(); 322 $u2 = $dg->create_user(); 323 324 $chat1a = $dg->create_module('chat', ['course' => $c1]); 325 $chat1b = $dg->create_module('chat', ['course' => $c1]); 326 $chat1actx = \context_module::instance($chat1a->cmid); 327 $chat1bctx = \context_module::instance($chat1b->cmid); 328 329 $u1chat1a = $this->login_user_in_course_chat($u1, $c1, $chat1a); 330 $u2chat1a = $this->login_user_in_course_chat($u2, $c1, $chat1a); 331 chat_send_chatmessage($u1chat1a, 'Ça va ?'); 332 chat_send_chatmessage($u2chat1a, 'Oui, et toi ?'); 333 chat_send_chatmessage($u1chat1a, 'Bien merci.'); 334 chat_send_chatmessage($u2chat1a, 'Pourquoi ils disent omelette "du" fromage ?!'); 335 chat_send_chatmessage($u1chat1a, 'Aucune idée'); 336 chat_send_chatmessage($u1chat1a, 'exit', true); 337 338 $u1chat1b = $this->login_user_in_course_chat($u1, $c1, $chat1b); 339 $u2chat1b = $this->login_user_in_course_chat($u2, $c1, $chat1b); 340 chat_send_chatmessage($u1chat1b, 'How are you going?'); 341 chat_send_chatmessage($u2chat1b, 'Alright, you?'); 342 chat_send_chatmessage($u1chat1b, 'Good, thanks.'); 343 chat_send_chatmessage($u2chat1b, 'Sacre bleu!'); 344 chat_send_chatmessage($u1chat1b, '\ö/'); 345 346 // Export for user 1 in chat 1. 347 provider::export_user_data(new approved_contextlist($u1, 'mod_chat', [$chat1actx->id])); 348 $data = writer::with_context($chat1actx)->get_data([]); 349 $this->assertNotEmpty($data); 350 $this->assertCount(5, $data->messages); 351 $this->assertEquals(get_string('messageenter', 'mod_chat', fullname($u1)), $data->messages[0]['message']); 352 $this->assertEquals(transform::yesno(true), $data->messages[0]['is_system_generated']); 353 $this->assertEquals('Ça va ?', $data->messages[1]['message']); 354 $this->assertEquals(transform::yesno(false), $data->messages[1]['is_system_generated']); 355 $this->assertEquals('Bien merci.', $data->messages[2]['message']); 356 $this->assertEquals(transform::yesno(false), $data->messages[2]['is_system_generated']); 357 $this->assertEquals('Aucune idée', $data->messages[3]['message']); 358 $this->assertEquals(transform::yesno(false), $data->messages[3]['is_system_generated']); 359 $this->assertEquals(get_string('messageexit', 'mod_chat', fullname($u1)), $data->messages[4]['message']); 360 $this->assertEquals(transform::yesno(true), $data->messages[4]['is_system_generated']); 361 $data = writer::with_context($chat1bctx)->get_data([]); 362 $this->assertEmpty($data); 363 364 // Export for user2 in chat 1 and 2. 365 writer::reset(); 366 provider::export_user_data(new approved_contextlist($u2, 'mod_chat', [$chat1actx->id, $chat1bctx->id])); 367 $data = writer::with_context($chat1actx)->get_data([]); 368 $this->assertNotEmpty($data); 369 $this->assertCount(3, $data->messages); 370 $this->assertEquals(get_string('messageenter', 'mod_chat', fullname($u2)), $data->messages[0]['message']); 371 $this->assertEquals('Oui, et toi ?', $data->messages[1]['message']); 372 $this->assertEquals('Pourquoi ils disent omelette "du" fromage ?!', $data->messages[2]['message']); 373 $data = writer::with_context($chat1bctx)->get_data([]); 374 $this->assertNotEmpty($data); 375 $this->assertCount(3, $data->messages); 376 $this->assertEquals(get_string('messageenter', 'mod_chat', fullname($u2)), $data->messages[0]['message']); 377 $this->assertEquals('Alright, you?', $data->messages[1]['message']); 378 $this->assertEquals('Sacre bleu!', $data->messages[2]['message']); 379 } 380 381 /** 382 * Assert that there is data for a user in a chat. 383 * 384 * @param object $user The user. 385 * @param object $chat The chat. 386 * @return void 387 */ 388 protected function assert_has_data_in_chat($user, $chat) { 389 $this->assertTrue($this->has_data_in_chat($user, $chat)); 390 } 391 392 /** 393 * Assert that there isn't any data for a user in a chat. 394 * 395 * @param object $user The user. 396 * @param object $chat The chat. 397 * @return void 398 */ 399 protected function assert_has_no_data_in_chat($user, $chat) { 400 $this->assertFalse($this->has_data_in_chat($user, $chat)); 401 } 402 403 /** 404 * Check whether a user has data in a chat. 405 * 406 * @param object $user The user. 407 * @param object $chat The chat. 408 * @return bool 409 */ 410 protected function has_data_in_chat($user, $chat) { 411 global $DB; 412 return $DB->record_exists('chat_messages', ['chatid' => $chat->id, 'userid' => $user->id]); 413 } 414 415 /** 416 * Login a user in a chat. 417 * 418 * @param object $user The user. 419 * @param object $course The course. 420 * @param object $chat The chat. 421 * @param int $group The group number. 422 * @param bool $silent Whether we should advertise that the user logs in. 423 * @return object The chat user. 424 */ 425 protected function login_user_in_course_chat($user, $course, $chat, $group = 0, $silent = false) { 426 global $DB, $USER; 427 $origuser = $USER; 428 $this->setUser($user); 429 chat_login_user($chat->id, $silent ? 'sockets' : 'basic', 0, $course); 430 $chatuser = $DB->get_record('chat_users', ['userid' => $user->id, 'chatid' => $chat->id, 'groupid' => 0]); 431 $this->setUser($origuser); 432 return $chatuser; 433 } 434 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body