Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 namespace core; 18 19 /** 20 * Tests for messagelib.php. 21 * 22 * @package core 23 * @category test 24 * @copyright 2012 The Open Universtiy 25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 26 */ 27 class messagelib_test extends \advanced_testcase { 28 29 public function test_message_provider_disabled() { 30 $this->resetAfterTest(); 31 $this->preventResetByRollback(); 32 33 // Disable instantmessage provider. 34 $disableprovidersetting = 'moodle_instantmessage_disable'; 35 set_config($disableprovidersetting, 1, 'message'); 36 $preferences = get_message_output_default_preferences(); 37 $this->assertTrue($preferences->$disableprovidersetting == 1); 38 39 $message = new \core\message\message(); 40 $message->courseid = 1; 41 $message->component = 'moodle'; 42 $message->name = 'instantmessage'; 43 $message->userfrom = get_admin(); 44 $message->userto = $this->getDataGenerator()->create_user();; 45 $message->subject = 'message subject 1'; 46 $message->fullmessage = 'message body'; 47 $message->fullmessageformat = FORMAT_MARKDOWN; 48 $message->fullmessagehtml = '<p>message body</p>'; 49 $message->smallmessage = 'small message'; 50 $message->notification = 0; 51 52 // Check message is not sent. 53 $sink = $this->redirectEmails(); 54 message_send($message); 55 $emails = $sink->get_messages(); 56 $this->assertEmpty($emails); 57 58 // Check message is sent. 59 set_config($disableprovidersetting, 0, 'message'); 60 $preferences = get_message_output_default_preferences(); 61 $this->assertTrue($preferences->$disableprovidersetting == 0); 62 63 $sink = $this->redirectEmails(); 64 message_send($message); 65 $emails = $sink->get_messages(); 66 $email = reset($emails); 67 $this->assertEquals(get_string('unreadnewmessage', 'message', fullname(get_admin())), $email->subject); 68 } 69 public function test_message_get_providers_for_user() { 70 global $CFG, $DB; 71 72 $this->resetAfterTest(); 73 74 $generator = $this->getDataGenerator(); 75 76 // Create a course category and course. 77 $cat = $generator->create_category(array('parent' => 0)); 78 $course = $generator->create_course(array('category' => $cat->id)); 79 $quiz = $generator->create_module('quiz', array('course' => $course->id)); 80 $user = $generator->create_user(); 81 82 $coursecontext = \context_course::instance($course->id); 83 $quizcontext = \context_module::instance($quiz->cmid); 84 $frontpagecontext = \context_course::instance(SITEID); 85 86 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 87 88 // The user is a student in a course, and has the capability for quiz 89 // confirmation emails in one quiz in that course. 90 role_assign($studentrole->id, $user->id, $coursecontext->id); 91 assign_capability('mod/quiz:emailconfirmsubmission', CAP_ALLOW, $studentrole->id, $quizcontext->id); 92 93 // Give this message type to the front page role. 94 assign_capability('mod/quiz:emailwarnoverdue', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext->id); 95 96 $providers = message_get_providers_for_user($user->id); 97 $this->assertTrue($this->message_type_present('mod_forum', 'posts', $providers)); 98 $this->assertTrue($this->message_type_present('mod_quiz', 'confirmation', $providers)); 99 $this->assertTrue($this->message_type_present('mod_quiz', 'attempt_overdue', $providers)); 100 $this->assertFalse($this->message_type_present('mod_quiz', 'submission', $providers)); 101 102 // A user is a student in a different course, they should not get confirmation. 103 $course2 = $generator->create_course(array('category' => $cat->id)); 104 $user2 = $generator->create_user(); 105 $coursecontext2 = \context_course::instance($course2->id); 106 role_assign($studentrole->id, $user2->id, $coursecontext2->id); 107 accesslib_clear_all_caches_for_unit_testing(); 108 $providers = message_get_providers_for_user($user2->id); 109 $this->assertTrue($this->message_type_present('mod_forum', 'posts', $providers)); 110 $this->assertFalse($this->message_type_present('mod_quiz', 'confirmation', $providers)); 111 112 // Now remove the frontpage role id, and attempt_overdue message should go away. 113 unset_config('defaultfrontpageroleid'); 114 accesslib_clear_all_caches_for_unit_testing(); 115 116 $providers = message_get_providers_for_user($user->id); 117 $this->assertTrue($this->message_type_present('mod_quiz', 'confirmation', $providers)); 118 $this->assertFalse($this->message_type_present('mod_quiz', 'attempt_overdue', $providers)); 119 $this->assertFalse($this->message_type_present('mod_quiz', 'submission', $providers)); 120 } 121 122 public function test_message_get_providers_for_user_more() { 123 global $DB; 124 125 $this->resetAfterTest(); 126 127 // Create a course. 128 $course = $this->getDataGenerator()->create_course(); 129 $coursecontext = \context_course::instance($course->id); 130 131 // It would probably be better to use a quiz instance as it has capability controlled messages 132 // however mod_quiz doesn't have a data generator. 133 // Instead we're going to use backup notifications and give and take away the capability at various levels. 134 $assign = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id)); 135 $modulecontext = \context_module::instance($assign->cmid); 136 137 // Create and enrol a teacher. 138 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 139 $teacher = $this->getDataGenerator()->create_user(); 140 role_assign($teacherrole->id, $teacher->id, $coursecontext); 141 $enrolplugin = enrol_get_plugin('manual'); 142 $enrolplugin->add_instance($course); 143 $enrolinstances = enrol_get_instances($course->id, false); 144 foreach ($enrolinstances as $enrolinstance) { 145 if ($enrolinstance->enrol === 'manual') { 146 break; 147 } 148 } 149 $enrolplugin->enrol_user($enrolinstance, $teacher->id); 150 151 // Make the teacher the current user. 152 $this->setUser($teacher); 153 154 // Teacher shouldn't have the required capability so they shouldn't be able to see the backup message. 155 $this->assertFalse(has_capability('moodle/site:config', $modulecontext)); 156 $providers = message_get_providers_for_user($teacher->id); 157 $this->assertFalse($this->message_type_present('moodle', 'backup', $providers)); 158 159 // Give the user the required capability in an activity module. 160 // They should now be able to see the backup message. 161 assign_capability('moodle/site:config', CAP_ALLOW, $teacherrole->id, $modulecontext->id, true); 162 accesslib_clear_all_caches_for_unit_testing(); 163 $modulecontext = \context_module::instance($assign->cmid); 164 $this->assertTrue(has_capability('moodle/site:config', $modulecontext)); 165 166 $providers = message_get_providers_for_user($teacher->id); 167 $this->assertTrue($this->message_type_present('moodle', 'backup', $providers)); 168 169 // Prohibit the capability for the user at the course level. 170 // This overrules the CAP_ALLOW at the module level. 171 // They should not be able to see the backup message. 172 assign_capability('moodle/site:config', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id, true); 173 accesslib_clear_all_caches_for_unit_testing(); 174 $modulecontext = \context_module::instance($assign->cmid); 175 $this->assertFalse(has_capability('moodle/site:config', $modulecontext)); 176 177 $providers = message_get_providers_for_user($teacher->id); 178 // Actually, handling PROHIBITs would be too expensive. We do not 179 // care if users with PROHIBITs see a few more preferences than they should. 180 // $this->assertFalse($this->message_type_present('moodle', 'backup', $providers)); 181 } 182 183 public function test_send_message_redirection() { 184 global $DB; 185 186 $this->resetAfterTest(); 187 188 $user1 = $this->getDataGenerator()->create_user(); 189 $user2 = $this->getDataGenerator()->create_user(); 190 191 // Test basic message redirection. 192 $message = new \core\message\message(); 193 $message->courseid = 1; 194 $message->component = 'moodle'; 195 $message->name = 'instantmessage'; 196 $message->userfrom = $user1; 197 $message->userto = $user2; 198 $message->subject = 'message subject 1'; 199 $message->fullmessage = 'message body'; 200 $message->fullmessageformat = FORMAT_MARKDOWN; 201 $message->fullmessagehtml = '<p>message body</p>'; 202 $message->smallmessage = 'small message'; 203 $message->notification = '0'; 204 $message->customdata = ['datakey' => 'data']; 205 206 $sink = $this->redirectMessages(); 207 $this->setCurrentTimeStart(); 208 $messageid = message_send($message); 209 $savedmessages = $sink->get_messages(); 210 $this->assertCount(1, $savedmessages); 211 $savedmessage = reset($savedmessages); 212 $this->assertEquals($messageid, $savedmessage->id); 213 $this->assertEquals($user1->id, $savedmessage->useridfrom); 214 $this->assertEquals($user2->id, $savedmessage->useridto); 215 $this->assertEquals($message->fullmessage, $savedmessage->fullmessage); 216 $this->assertEquals($message->fullmessageformat, $savedmessage->fullmessageformat); 217 $this->assertEquals($message->fullmessagehtml, $savedmessage->fullmessagehtml); 218 $this->assertEquals($message->smallmessage, $savedmessage->smallmessage); 219 $this->assertEquals($message->smallmessage, $savedmessage->smallmessage); 220 $this->assertEquals($message->notification, $savedmessage->notification); 221 $this->assertEquals($message->customdata, $savedmessage->customdata); 222 $this->assertStringContainsString('datakey', $savedmessage->customdata); 223 // Check it was a unserialisable json. 224 $customdata = json_decode($savedmessage->customdata); 225 $this->assertEquals('data', $customdata->datakey); 226 $this->assertEquals(1, $customdata->courseid); 227 $this->assertTimeCurrent($savedmessage->timecreated); 228 $record = $DB->get_record('messages', array('id' => $savedmessage->id), '*', MUST_EXIST); 229 unset($savedmessage->useridto); 230 unset($savedmessage->notification); 231 $this->assertEquals($record, $savedmessage); 232 $sink->clear(); 233 $this->assertTrue($DB->record_exists('message_user_actions', array('userid' => $user2->id, 'messageid' => $messageid, 234 'action' => \core_message\api::MESSAGE_ACTION_READ))); 235 $DB->delete_records('messages', array()); 236 237 $message = new \core\message\message(); 238 $message->courseid = 1; 239 $message->component = 'moodle'; 240 $message->name = 'instantmessage'; 241 $message->userfrom = $user1->id; 242 $message->userto = $user2->id; 243 $message->subject = 'message subject 1'; 244 $message->fullmessage = 'message body'; 245 $message->fullmessageformat = FORMAT_MARKDOWN; 246 $message->fullmessagehtml = '<p>message body</p>'; 247 $message->smallmessage = 'small message'; 248 $message->notification = '0'; 249 250 $sink = $this->redirectMessages(); 251 $messageid = message_send($message); 252 $savedmessages = $sink->get_messages(); 253 $this->assertCount(1, $savedmessages); 254 $savedmessage = reset($savedmessages); 255 $this->assertEquals($messageid, $savedmessage->id); 256 $this->assertEquals($user1->id, $savedmessage->useridfrom); 257 $this->assertEquals($user2->id, $savedmessage->useridto); 258 $this->assertEquals($message->fullmessage, $savedmessage->fullmessage); 259 $this->assertEquals($message->fullmessageformat, $savedmessage->fullmessageformat); 260 $this->assertEquals($message->fullmessagehtml, $savedmessage->fullmessagehtml); 261 $this->assertEquals($message->smallmessage, $savedmessage->smallmessage); 262 $this->assertEquals($message->smallmessage, $savedmessage->smallmessage); 263 $this->assertEquals($message->notification, $savedmessage->notification); 264 $this->assertTimeCurrent($savedmessage->timecreated); 265 $record = $DB->get_record('messages', array('id' => $savedmessage->id), '*', MUST_EXIST); 266 unset($savedmessage->useridto); 267 unset($savedmessage->notification); 268 $this->assertEquals($record, $savedmessage); 269 $sink->clear(); 270 $this->assertTrue($DB->record_exists('message_user_actions', array('userid' => $user2->id, 'messageid' => $messageid, 271 'action' => \core_message\api::MESSAGE_ACTION_READ))); 272 $DB->delete_records('messages', array()); 273 274 // Test phpunit problem detection. 275 276 $message = new \core\message\message(); 277 $message->courseid = 1; 278 $message->component = 'xxxxx'; 279 $message->name = 'instantmessage'; 280 $message->userfrom = $user1; 281 $message->userto = $user2; 282 $message->subject = 'message subject 1'; 283 $message->fullmessage = 'message body'; 284 $message->fullmessageformat = FORMAT_MARKDOWN; 285 $message->fullmessagehtml = '<p>message body</p>'; 286 $message->smallmessage = 'small message'; 287 $message->notification = '0'; 288 289 $sink = $this->redirectMessages(); 290 try { 291 message_send($message); 292 } catch (\moodle_exception $e) { 293 $this->assertInstanceOf('coding_exception', $e); 294 } 295 $this->assertCount(0, $sink->get_messages()); 296 $this->assertDebuggingCalled('Attempt to send msg from a provider xxxxx/instantmessage '. 297 'that is inactive or not allowed for the user id='.$user2->id); 298 299 $message->component = 'moodle'; 300 $message->name = 'xxx'; 301 $sink = $this->redirectMessages(); 302 try { 303 message_send($message); 304 } catch (\moodle_exception $e) { 305 $this->assertInstanceOf('coding_exception', $e); 306 } 307 $this->assertCount(0, $sink->get_messages()); 308 $this->assertDebuggingCalled('Attempt to send msg from a provider moodle/xxx '. 309 'that is inactive or not allowed for the user id='.$user2->id); 310 $sink->close(); 311 $this->assertFalse($DB->record_exists('messages', array())); 312 313 // Invalid users. 314 315 $message = new \core\message\message(); 316 $message->courseid = 1; 317 $message->component = 'moodle'; 318 $message->name = 'instantmessage'; 319 $message->userfrom = $user1; 320 $message->userto = -1; 321 $message->subject = 'message subject 1'; 322 $message->fullmessage = 'message body'; 323 $message->fullmessageformat = FORMAT_MARKDOWN; 324 $message->fullmessagehtml = '<p>message body</p>'; 325 $message->smallmessage = 'small message'; 326 $message->notification = '0'; 327 328 $messageid = message_send($message); 329 $this->assertFalse($messageid); 330 $this->assertDebuggingCalled('Attempt to send msg to unknown user'); 331 332 $message = new \core\message\message(); 333 $message->courseid = 1; 334 $message->component = 'moodle'; 335 $message->name = 'instantmessage'; 336 $message->userfrom = -1; 337 $message->userto = $user2; 338 $message->subject = 'message subject 1'; 339 $message->fullmessage = 'message body'; 340 $message->fullmessageformat = FORMAT_MARKDOWN; 341 $message->fullmessagehtml = '<p>message body</p>'; 342 $message->smallmessage = 'small message'; 343 $message->notification = '0'; 344 345 $messageid = message_send($message); 346 $this->assertFalse($messageid); 347 $this->assertDebuggingCalled('Attempt to send msg from unknown user'); 348 349 $message = new \core\message\message(); 350 $message->courseid = 1; 351 $message->component = 'moodle'; 352 $message->name = 'instantmessage'; 353 $message->userfrom = $user1; 354 $message->userto = \core_user::NOREPLY_USER; 355 $message->subject = 'message subject 1'; 356 $message->fullmessage = 'message body'; 357 $message->fullmessageformat = FORMAT_MARKDOWN; 358 $message->fullmessagehtml = '<p>message body</p>'; 359 $message->smallmessage = 'small message'; 360 $message->notification = '0'; 361 362 $messageid = message_send($message); 363 $this->assertFalse($messageid); 364 $this->assertDebuggingCalled('Attempt to send msg to internal (noreply) user'); 365 366 // Some debugging hints for devs. 367 368 unset($user2->emailstop); 369 $message = new \core\message\message(); 370 $message->courseid = 1; 371 $message->component = 'moodle'; 372 $message->name = 'instantmessage'; 373 $message->userfrom = $user1; 374 $message->userto = $user2; 375 $message->subject = 'message subject 1'; 376 $message->fullmessage = 'message body'; 377 $message->fullmessageformat = FORMAT_MARKDOWN; 378 $message->fullmessagehtml = '<p>message body</p>'; 379 $message->smallmessage = 'small message'; 380 $message->notification = '0'; 381 382 $sink = $this->redirectMessages(); 383 $messageid = message_send($message); 384 $savedmessages = $sink->get_messages(); 385 $this->assertCount(1, $savedmessages); 386 $savedmessage = reset($savedmessages); 387 $this->assertEquals($messageid, $savedmessage->id); 388 $this->assertEquals($user1->id, $savedmessage->useridfrom); 389 $this->assertEquals($user2->id, $savedmessage->useridto); 390 $this->assertDebuggingCalled('Necessary properties missing in userto object, fetching full record'); 391 $sink->clear(); 392 $user2->emailstop = '0'; 393 } 394 395 public function test_send_message() { 396 global $DB, $CFG; 397 $this->preventResetByRollback(); 398 $this->resetAfterTest(); 399 400 $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); 401 $user2 = $this->getDataGenerator()->create_user(); 402 set_config('allowedemaildomains', 'example.com'); 403 404 // Test basic email redirection. 405 $this->assertFileExists("$CFG->dirroot/message/output/email/version.php"); 406 $this->assertFileExists("$CFG->dirroot/message/output/popup/version.php"); 407 408 $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email' AND name <> 'popup'"); 409 get_message_processors(true, true); 410 411 $eventsink = $this->redirectEvents(); 412 413 // Will always use the pop-up processor. 414 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'none', $user2); 415 416 $message = new \core\message\message(); 417 $message->courseid = 1; 418 $message->component = 'moodle'; 419 $message->name = 'instantmessage'; 420 $message->userfrom = $user1; 421 $message->userto = $user2; 422 $message->subject = 'message subject 1'; 423 $message->fullmessage = 'message body'; 424 $message->fullmessageformat = FORMAT_MARKDOWN; 425 $message->fullmessagehtml = '<p>message body</p>'; 426 $message->smallmessage = 'small message'; 427 $message->notification = '0'; 428 429 $sink = $this->redirectEmails(); 430 $messageid = message_send($message); 431 $emails = $sink->get_messages(); 432 $this->assertCount(0, $emails); 433 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 434 $sink->clear(); 435 $this->assertFalse($DB->record_exists('message_user_actions', array())); 436 $DB->delete_records('messages', array()); 437 $DB->delete_records('message_user_actions', array()); 438 $events = $eventsink->get_events(); 439 $this->assertCount(1, $events); 440 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 441 $eventsink->clear(); 442 443 // No messages are sent when the feature is disabled. 444 $CFG->messaging = 0; 445 446 $message = new \core\message\message(); 447 $message->courseid = 1; 448 $message->component = 'moodle'; 449 $message->name = 'instantmessage'; 450 $message->userfrom = $user1; 451 $message->userto = $user2; 452 $message->subject = 'message subject 1'; 453 $message->fullmessage = 'message body'; 454 $message->fullmessageformat = FORMAT_MARKDOWN; 455 $message->fullmessagehtml = '<p>message body</p>'; 456 $message->smallmessage = 'small message'; 457 $message->notification = '0'; 458 459 $messageid = message_send($message); 460 $this->assertFalse($messageid); 461 $this->assertDebuggingCalled('Attempt to send msg from a provider moodle/instantmessage '. 462 'that is inactive or not allowed for the user id='.$user2->id); 463 $emails = $sink->get_messages(); 464 $this->assertCount(0, $emails); 465 $sink->clear(); 466 $DB->delete_records('messages', array()); 467 $DB->delete_records('message_user_actions', array()); 468 $events = $eventsink->get_events(); 469 $this->assertCount(0, $events); 470 $eventsink->clear(); 471 472 // Example of a message that is sent and viewed. 473 $CFG->messaging = 1; 474 475 $message = new \core\message\message(); 476 $message->courseid = 1; 477 $message->component = 'moodle'; 478 $message->name = 'instantmessage'; 479 $message->userfrom = $user1; 480 $message->userto = $user2; 481 $message->subject = 'message subject 1'; 482 $message->fullmessage = 'message body'; 483 $message->fullmessageformat = FORMAT_MARKDOWN; 484 $message->fullmessagehtml = '<p>message body</p>'; 485 $message->smallmessage = 'small message'; 486 $message->notification = '1'; 487 488 $messageid = message_send($message); 489 $emails = $sink->get_messages(); 490 $this->assertCount(0, $emails); 491 $savedmessage = $DB->get_record('notifications', array('id' => $messageid), '*', MUST_EXIST); 492 $sink->clear(); 493 $this->assertFalse($DB->record_exists('messages', array())); 494 $DB->delete_records('notifications', array()); 495 $events = $eventsink->get_events(); 496 $this->assertCount(2, $events); 497 $this->assertInstanceOf('\core\event\notification_sent', $events[0]); 498 $this->assertInstanceOf('\core\event\notification_viewed', $events[1]); 499 $eventsink->clear(); 500 501 // Will always use the pop-up processor. 502 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); 503 504 $message = new \core\message\message(); 505 $message->courseid = 1; 506 $message->component = 'moodle'; 507 $message->name = 'instantmessage'; 508 $message->userfrom = $user1; 509 $message->userto = $user2; 510 $message->subject = 'message subject 1'; 511 $message->fullmessage = 'message body'; 512 $message->fullmessageformat = FORMAT_MARKDOWN; 513 $message->fullmessagehtml = '<p>message body</p>'; 514 $message->smallmessage = 'small message'; 515 $message->notification = '0'; 516 517 $user2->emailstop = '1'; 518 519 $sink = $this->redirectEmails(); 520 $messageid = message_send($message); 521 $emails = $sink->get_messages(); 522 $this->assertCount(0, $emails); 523 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 524 $sink->clear(); 525 $this->assertFalse($DB->record_exists('message_user_actions', array())); 526 $DB->delete_records('messages', array()); 527 $DB->delete_records('message_user_actions', array()); 528 $events = $eventsink->get_events(); 529 $this->assertCount(1, $events); 530 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 531 $eventsink->clear(); 532 $user2->emailstop = '0'; 533 534 // Will always use the pop-up processor. 535 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); 536 537 $message = new \core\message\message(); 538 $message->courseid = 1; 539 $message->component = 'moodle'; 540 $message->name = 'instantmessage'; 541 $message->userfrom = $user1; 542 $message->userto = $user2; 543 $message->subject = 'message subject 1'; 544 $message->fullmessage = 'message body'; 545 $message->fullmessageformat = FORMAT_MARKDOWN; 546 $message->fullmessagehtml = '<p>message body</p>'; 547 $message->smallmessage = 'small message'; 548 $message->notification = '0'; 549 550 $messageid = message_send($message); 551 $emails = $sink->get_messages(); 552 $this->assertCount(1, $emails); 553 $email = reset($emails); 554 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 555 $this->assertSame($user1->email, $email->from); 556 $this->assertSame($user2->email, $email->to); 557 $this->assertSame(get_string('unreadnewmessage', 'message', fullname($user1)), $email->subject); 558 $this->assertNotEmpty($email->header); 559 $this->assertNotEmpty($email->body); 560 $sink->clear(); 561 $this->assertFalse($DB->record_exists('message_user_actions', array())); 562 $DB->delete_records('message_user_actions', array()); 563 $events = $eventsink->get_events(); 564 $this->assertCount(1, $events); 565 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 566 $eventsink->clear(); 567 568 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email,popup', $user2); 569 570 $message = new \core\message\message(); 571 $message->courseid = 1; 572 $message->component = 'moodle'; 573 $message->name = 'instantmessage'; 574 $message->userfrom = $user1; 575 $message->userto = $user2; 576 $message->subject = 'message subject 1'; 577 $message->fullmessage = 'message body'; 578 $message->fullmessageformat = FORMAT_MARKDOWN; 579 $message->fullmessagehtml = '<p>message body</p>'; 580 $message->smallmessage = 'small message'; 581 $message->notification = '0'; 582 583 $messageid = message_send($message); 584 $emails = $sink->get_messages(); 585 $this->assertCount(1, $emails); 586 $email = reset($emails); 587 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 588 $this->assertSame($user1->email, $email->from); 589 $this->assertSame($user2->email, $email->to); 590 $this->assertSame(get_string('unreadnewmessage', 'message', fullname($user1)), $email->subject); 591 $this->assertNotEmpty($email->header); 592 $this->assertNotEmpty($email->body); 593 $sink->clear(); 594 $this->assertFalse($DB->record_exists('message_user_actions', array())); 595 $DB->delete_records('messages', array()); 596 $DB->delete_records('message_user_actions', array()); 597 $events = $eventsink->get_events(); 598 $this->assertCount(1, $events); 599 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 600 $eventsink->clear(); 601 602 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'popup', $user2); 603 604 $message = new \core\message\message(); 605 $message->courseid = 1; 606 $message->component = 'moodle'; 607 $message->name = 'instantmessage'; 608 $message->userfrom = $user1; 609 $message->userto = $user2; 610 $message->subject = 'message subject 1'; 611 $message->fullmessage = 'message body'; 612 $message->fullmessageformat = FORMAT_MARKDOWN; 613 $message->fullmessagehtml = '<p>message body</p>'; 614 $message->smallmessage = 'small message'; 615 $message->notification = '0'; 616 617 $messageid = message_send($message); 618 $emails = $sink->get_messages(); 619 $this->assertCount(0, $emails); 620 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 621 $sink->clear(); 622 $this->assertFalse($DB->record_exists('message_user_actions', array())); 623 $DB->delete_records('messages', array()); 624 $events = $eventsink->get_events(); 625 $this->assertCount(1, $events); 626 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 627 $eventsink->clear(); 628 629 $this->assertFalse($DB->is_transaction_started()); 630 $transaction = $DB->start_delegated_transaction(); 631 if (!$DB->is_transaction_started()) { 632 $this->markTestSkipped('Databases that do not support transactions should not be used at all!'); 633 } 634 $transaction->allow_commit(); 635 636 // Will always use the pop-up processor. 637 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'none', $user2); 638 639 $message = new \core\message\message(); 640 $message->courseid = 1; 641 $message->component = 'moodle'; 642 $message->name = 'instantmessage'; 643 $message->userfrom = $user1; 644 $message->userto = $user2; 645 $message->subject = 'message subject 1'; 646 $message->fullmessage = 'message body'; 647 $message->fullmessageformat = FORMAT_MARKDOWN; 648 $message->fullmessagehtml = '<p>message body</p>'; 649 $message->smallmessage = 'small message'; 650 $message->notification = '0'; 651 652 $transaction = $DB->start_delegated_transaction(); 653 $sink = $this->redirectEmails(); 654 $messageid = message_send($message); 655 $emails = $sink->get_messages(); 656 $this->assertCount(0, $emails); 657 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 658 $sink->clear(); 659 $this->assertFalse($DB->record_exists('message_user_actions', array())); 660 $DB->delete_records('messages', array()); 661 $events = $eventsink->get_events(); 662 $this->assertCount(0, $events); 663 $eventsink->clear(); 664 $transaction->allow_commit(); 665 $events = $eventsink->get_events(); 666 $this->assertCount(1, $events); 667 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 668 669 // Will always use the pop-up processor. 670 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); 671 672 $message = new \core\message\message(); 673 $message->courseid = 1; 674 $message->component = 'moodle'; 675 $message->name = 'instantmessage'; 676 $message->userfrom = $user1; 677 $message->userto = $user2; 678 $message->subject = 'message subject 1'; 679 $message->fullmessage = 'message body'; 680 $message->fullmessageformat = FORMAT_MARKDOWN; 681 $message->fullmessagehtml = '<p>message body</p>'; 682 $message->smallmessage = 'small message'; 683 $message->notification = '0'; 684 685 $transaction = $DB->start_delegated_transaction(); 686 $sink = $this->redirectEmails(); 687 $messageid = message_send($message); 688 $emails = $sink->get_messages(); 689 $this->assertCount(0, $emails); 690 $savedmessage = $DB->get_record('messages', array('id' => $messageid), '*', MUST_EXIST); 691 $sink->clear(); 692 $this->assertFalse($DB->record_exists('message_user_actions', array())); 693 $events = $eventsink->get_events(); 694 $this->assertCount(1, $events); 695 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 696 $transaction->allow_commit(); 697 $events = $eventsink->get_events(); 698 $this->assertCount(2, $events); 699 $this->assertInstanceOf('\core\event\message_sent', $events[1]); 700 $eventsink->clear(); 701 702 $transaction = $DB->start_delegated_transaction(); 703 message_send($message); 704 message_send($message); 705 $this->assertCount(3, $DB->get_records('messages')); 706 $this->assertFalse($DB->record_exists('message_user_actions', array())); 707 $events = $eventsink->get_events(); 708 $this->assertCount(0, $events); 709 $transaction->allow_commit(); 710 $events = $eventsink->get_events(); 711 $this->assertCount(2, $events); 712 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 713 $this->assertInstanceOf('\core\event\message_sent', $events[1]); 714 $eventsink->clear(); 715 $DB->delete_records('messages', array()); 716 717 $transaction = $DB->start_delegated_transaction(); 718 message_send($message); 719 message_send($message); 720 $this->assertCount(2, $DB->get_records('messages')); 721 $this->assertCount(0, $DB->get_records('message_user_actions')); 722 $events = $eventsink->get_events(); 723 $this->assertCount(0, $events); 724 try { 725 $transaction->rollback(new \Exception('ignore')); 726 } catch (\Exception $e) { 727 $this->assertSame('ignore', $e->getMessage()); 728 } 729 $events = $eventsink->get_events(); 730 $this->assertCount(0, $events); 731 $this->assertCount(0, $DB->get_records('messages')); 732 message_send($message); 733 $this->assertCount(1, $DB->get_records('messages')); 734 $this->assertCount(0, $DB->get_records('message_user_actions')); 735 $events = $eventsink->get_events(); 736 $this->assertCount(1, $events); 737 $this->assertInstanceOf('\core\event\message_sent', $events[0]); 738 $sink->clear(); 739 } 740 741 /** 742 * Tests calling message_send() with $eventdata representing a message to an individual conversation. 743 * 744 * This test will verify: 745 * - that the 'messages' record is created. 746 * - that the processors will be called for each conversation member, except the sender. 747 * - the a single event will be generated - 'message_sent' 748 * 749 * Note: We won't redirect/capture messages in this test because doing so causes message_send() to return early, before 750 * processors and events code is called. We need to test this code here, as we generally redirect messages elsewhere and we 751 * need to be sure this is covered. 752 */ 753 public function test_message_send_to_conversation_individual() { 754 global $DB; 755 $this->preventResetByRollback(); 756 $this->resetAfterTest(); 757 758 // Create some users and a conversation between them. 759 $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); 760 $user2 = $this->getDataGenerator()->create_user(); 761 set_config('allowedemaildomains', 'example.com'); 762 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 763 [$user1->id, $user2->id], '1:1 project discussion'); 764 765 // Generate the message. 766 $message = new \core\message\message(); 767 $message->courseid = 1; 768 $message->component = 'moodle'; 769 $message->name = 'instantmessage'; 770 $message->userfrom = $user1; 771 $message->convid = $conversation->id; 772 $message->subject = 'message subject 1'; 773 $message->fullmessage = 'message body'; 774 $message->fullmessageformat = FORMAT_MARKDOWN; 775 $message->fullmessagehtml = '<p>message body</p>'; 776 $message->smallmessage = 'small message'; 777 $message->notification = '0'; 778 779 // Content specific to the email processor. 780 $content = array('*' => array('header' => ' test ', 'footer' => ' test ')); 781 $message->set_additional_content('email', $content); 782 783 // Ensure we're going to hit the email processor for this user. 784 $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); 785 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); 786 787 // Now, send a message and verify the message processors (in this case, email) are hit. 788 $sink = $this->redirectEmails(); 789 $messageid = message_send($message); 790 $emails = $sink->get_messages(); 791 $this->assertCount(1, $emails); 792 $email = reset($emails); 793 794 // Verify the record was created in 'messages'. 795 $recordexists = $DB->record_exists('messages', ['id' => $messageid]); 796 $this->assertTrue($recordexists); 797 798 // Verify the email information. 799 $this->assertSame($user1->email, $email->from); 800 $this->assertSame($user2->email, $email->to); 801 802 // The message subject is generated during the call for conversation messages, 803 // as the conversation may have many members having different lang preferences. 804 $this->assertSame(get_string('unreadnewmessage', 'message', fullname($user1)), $email->subject); 805 806 // The email content will have had an emailtagline appended to it, based on lang prefs, 807 // so verify the expected beginning and ends. 808 $this->assertNotEmpty($email->header); 809 $this->assertNotEmpty($email->body); 810 $this->assertMatchesRegularExpression('/test.*message body.*test/s', $email->body); 811 $sink->clear(); 812 813 // Now, send the message again, and verify that the event fired includes the courseid and conversationid. 814 $eventsink = $this->redirectEvents(); 815 $messageid = message_send($message); 816 $events = $eventsink->get_events(); 817 $this->assertCount(1, $events); 818 $event = reset($events); 819 $this->assertInstanceOf(\core\event\message_sent::class, $event); 820 $this->assertEquals($user1->id, $event->userid); 821 $this->assertEquals($user2->id, $event->relateduserid); 822 $this->assertEquals($message->courseid, $event->other['courseid']); 823 824 $eventsink->clear(); 825 $sink->clear(); 826 } 827 828 /** 829 * Tests calling message_send() with $eventdata representing a message to a self-conversation. 830 * 831 * This test will verify: 832 * - that the 'messages' record is created. 833 * - that the processors is not called (for now self-conversations are not processed). 834 * - the a single event will be generated - 'message_sent' 835 * 836 * Note: We won't redirect/capture messages in this test because doing so causes message_send() to return early, before 837 * processors and events code is called. We need to test this code here, as we generally redirect messages elsewhere and we 838 * need to be sure this is covered. 839 */ 840 public function test_message_send_to_self_conversation() { 841 global $DB; 842 $this->preventResetByRollback(); 843 $this->resetAfterTest(); 844 845 // Create some users and a conversation between them. 846 $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); 847 set_config('allowedemaildomains', 'example.com'); 848 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, 849 [$user1->id]); 850 851 // Generate the message. 852 $message = new \core\message\message(); 853 $message->courseid = 1; 854 $message->component = 'moodle'; 855 $message->name = 'instantmessage'; 856 $message->userfrom = $user1; 857 $message->convid = $conversation->id; 858 $message->subject = 'message subject 1'; 859 $message->fullmessage = 'message body'; 860 $message->fullmessageformat = FORMAT_MARKDOWN; 861 $message->fullmessagehtml = '<p>message body</p>'; 862 $message->smallmessage = 'small message'; 863 $message->notification = '0'; 864 865 // Content specific to the email processor. 866 $content = array('*' => array('header' => ' test ', 'footer' => ' test ')); 867 $message->set_additional_content('email', $content); 868 869 // Ensure we're going to hit the email processor for this user. 870 $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); 871 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user1); 872 873 // Now, send a message and verify the message processors are empty (self-conversations are not processed for now). 874 $sink = $this->redirectEmails(); 875 $messageid = message_send($message); 876 $emails = $sink->get_messages(); 877 $this->assertCount(0, $emails); 878 $sink->clear(); 879 } 880 881 /** 882 * Tests calling message_send() with $eventdata representing a message to an group conversation. 883 * 884 * This test will verify: 885 * - that the 'messages' record is created. 886 * - that the processors will be called for each conversation member, except the sender. 887 * - the a single event will be generated - 'group_message_sent' 888 * 889 * Note: We won't redirect/capture messages in this test because doing so causes message_send() to return early, before 890 * processors and events code is called. We need to test this code here, as we generally redirect messages elsewhere and we 891 * need to be sure this is covered. 892 */ 893 public function test_message_send_to_conversation_group() { 894 global $DB; 895 $this->preventResetByRollback(); 896 $this->resetAfterTest(); 897 898 $course = $this->getDataGenerator()->create_course(); 899 900 // Create some users and a conversation between them. 901 $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); 902 $user2 = $this->getDataGenerator()->create_user(); 903 $user3 = $this->getDataGenerator()->create_user(); 904 set_config('allowedemaildomains', 'example.com'); 905 906 // Create a group in the course. 907 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 908 groups_add_member($group1->id, $user1->id); 909 groups_add_member($group1->id, $user2->id); 910 groups_add_member($group1->id, $user3->id); 911 912 $conversation = \core_message\api::create_conversation( 913 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 914 [$user1->id, $user2->id, $user3->id], 915 'Group project discussion', 916 \core_message\api::MESSAGE_CONVERSATION_ENABLED, 917 'core_group', 918 'groups', 919 $group1->id, 920 \context_course::instance($course->id)->id 921 ); 922 923 // Generate the message. 924 $message = new \core\message\message(); 925 $message->courseid = 1; 926 $message->component = 'moodle'; 927 $message->name = 'instantmessage'; 928 $message->userfrom = $user1; 929 $message->convid = $conversation->id; 930 $message->subject = 'message subject 1'; 931 $message->fullmessage = 'message body'; 932 $message->fullmessageformat = FORMAT_MARKDOWN; 933 $message->fullmessagehtml = '<p>message body</p>'; 934 $message->smallmessage = 'small message'; 935 $message->notification = '0'; 936 937 // Content specific to the email processor. 938 $content = array('*' => array('header' => ' test ', 'footer' => ' test ')); 939 $message->set_additional_content('email', $content); 940 941 // Ensure the email processor is enabled for the recipient users. 942 $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); 943 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); 944 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user3); 945 946 // Now, send a message and verify the email processor are hit. 947 $messageid = message_send($message); 948 949 $sink = $this->redirectEmails(); 950 $task = new \message_email\task\send_email_task(); 951 $task->execute(); 952 $emails = $sink->get_messages(); 953 $this->assertCount(2, $emails); 954 955 // Verify the record was created in 'messages'. 956 $recordexists = $DB->record_exists('messages', ['id' => $messageid]); 957 $this->assertTrue($recordexists); 958 959 // Now, send the message again, and verify that the event fired includes the courseid and conversationid. 960 $eventsink = $this->redirectEvents(); 961 $messageid = message_send($message); 962 $events = $eventsink->get_events(); 963 $this->assertCount(1, $events); 964 $event = reset($events); 965 $this->assertInstanceOf(\core\event\group_message_sent::class, $event); 966 $this->assertEquals($user1->id, $event->userid); 967 $this->assertNull($event->relateduserid); 968 $this->assertEquals($message->courseid, $event->other['courseid']); 969 $this->assertEquals($message->convid, $event->other['conversationid']); 970 $eventsink->clear(); 971 $sink->clear(); 972 } 973 974 /** 975 * Verify that sending a message to a conversation is an action which can be buffered by the manager if in a DB transaction. 976 * 977 * This should defer all processor calls (for 2 members in this case), and event creation (1 event). 978 */ 979 public function test_send_message_to_conversation_group_with_buffering() { 980 global $DB, $CFG; 981 $this->preventResetByRollback(); 982 $this->resetAfterTest(); 983 984 $course = $this->getDataGenerator()->create_course(); 985 986 $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); 987 $user2 = $this->getDataGenerator()->create_user(); 988 $user3 = $this->getDataGenerator()->create_user(); 989 set_config('allowedemaildomains', 'example.com'); 990 991 // Create a group in the course. 992 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 993 groups_add_member($group1->id, $user1->id); 994 groups_add_member($group1->id, $user2->id); 995 groups_add_member($group1->id, $user3->id); 996 997 $conversation = \core_message\api::create_conversation( 998 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 999 [$user1->id, $user2->id, $user3->id], 1000 'Group project discussion', 1001 \core_message\api::MESSAGE_CONVERSATION_ENABLED, 1002 'core_group', 1003 'groups', 1004 $group1->id, 1005 \context_course::instance($course->id)->id 1006 ); 1007 1008 // Test basic email redirection. 1009 $this->assertFileExists("$CFG->dirroot/message/output/email/version.php"); 1010 $this->assertFileExists("$CFG->dirroot/message/output/popup/version.php"); 1011 1012 $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email' AND name <> 'popup'"); 1013 get_message_processors(true, true); 1014 1015 $eventsink = $this->redirectEvents(); 1016 1017 // Will always use the pop-up processor. 1018 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); 1019 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user3); 1020 1021 $message = new \core\message\message(); 1022 $message->courseid = 1; 1023 $message->component = 'moodle'; 1024 $message->name = 'instantmessage'; 1025 $message->userfrom = $user1; 1026 $message->convid = $conversation->id; 1027 $message->subject = 'message subject 1'; 1028 $message->fullmessage = 'message body'; 1029 $message->fullmessageformat = FORMAT_MARKDOWN; 1030 $message->fullmessagehtml = '<p>message body</p>'; 1031 $message->smallmessage = 'small message'; 1032 $message->notification = '0'; 1033 1034 $transaction = $DB->start_delegated_transaction(); 1035 $sink = $this->redirectEmails(); 1036 message_send($message); 1037 $emails = $sink->get_messages(); 1038 $this->assertCount(0, $emails); 1039 $sink->clear(); 1040 $this->assertFalse($DB->record_exists('message_user_actions', array())); 1041 $events = $eventsink->get_events(); 1042 $this->assertCount(0, $events); 1043 $eventsink->clear(); 1044 $transaction->allow_commit(); 1045 $events = $eventsink->get_events(); 1046 $task = new \message_email\task\send_email_task(); 1047 $task->execute(); 1048 $emails = $sink->get_messages(); 1049 $this->assertCount(2, $emails); 1050 $this->assertCount(1, $events); 1051 $this->assertInstanceOf('\core\event\group_message_sent', $events[0]); 1052 } 1053 1054 public function test_rollback() { 1055 global $DB; 1056 1057 $this->resetAfterTest(); 1058 $this->preventResetByRollback(); 1059 1060 $user1 = $this->getDataGenerator()->create_user(); 1061 $user2 = $this->getDataGenerator()->create_user(); 1062 1063 $message = new \core\message\message(); 1064 $message->courseid = 1; 1065 $message->component = 'moodle'; 1066 $message->name = 'instantmessage'; 1067 $message->userfrom = $user1; 1068 $message->userto = $user2; 1069 $message->subject = 'message subject 1'; 1070 $message->fullmessage = 'message body'; 1071 $message->fullmessageformat = FORMAT_MARKDOWN; 1072 $message->fullmessagehtml = '<p>message body</p>'; 1073 $message->smallmessage = 'small message'; 1074 $message->notification = '0'; 1075 1076 $mailsink = $this->redirectEmails(); 1077 1078 // Sending outside of a transaction is fine. 1079 message_send($message); 1080 $this->assertEquals(1, $mailsink->count()); 1081 1082 $transaction1 = $DB->start_delegated_transaction(); 1083 1084 $mailsink->clear(); 1085 message_send($message); 1086 $this->assertEquals(0, $mailsink->count()); 1087 1088 $transaction2 = $DB->start_delegated_transaction(); 1089 1090 $mailsink->clear(); 1091 message_send($message); 1092 $this->assertEquals(0, $mailsink->count()); 1093 1094 try { 1095 $transaction2->rollback(new \Exception('x')); 1096 $this->fail('Expecting exception'); 1097 } catch (\Exception $e) {} 1098 $this->assertDebuggingNotCalled(); 1099 $this->assertEquals(0, $mailsink->count()); 1100 1101 $this->assertTrue($DB->is_transaction_started()); 1102 1103 try { 1104 $transaction1->rollback(new \Exception('x')); 1105 $this->fail('Expecting exception'); 1106 } catch (\Exception $e) {} 1107 $this->assertDebuggingNotCalled(); 1108 $this->assertEquals(0, $mailsink->count()); 1109 1110 $this->assertFalse($DB->is_transaction_started()); 1111 1112 message_send($message); 1113 $this->assertEquals(1, $mailsink->count()); 1114 } 1115 1116 public function test_forced_rollback() { 1117 global $DB; 1118 1119 $this->resetAfterTest(); 1120 $this->preventResetByRollback(); 1121 set_config('noemailever', 1); 1122 1123 $user1 = $this->getDataGenerator()->create_user(); 1124 $user2 = $this->getDataGenerator()->create_user(); 1125 1126 $message = new \core\message\message(); 1127 $message->courseid = 1; 1128 $message->component = 'moodle'; 1129 $message->name = 'instantmessage'; 1130 $message->userfrom = $user1; 1131 $message->userto = $user2; 1132 $message->subject = 'message subject 1'; 1133 $message->fullmessage = 'message body'; 1134 $message->fullmessageformat = FORMAT_MARKDOWN; 1135 $message->fullmessagehtml = '<p>message body</p>'; 1136 $message->smallmessage = 'small message'; 1137 $message->notification = '0'; 1138 1139 message_send($message); 1140 $this->assertDebuggingCalled('Not sending email due to $CFG->noemailever config setting'); 1141 1142 $transaction1 = $DB->start_delegated_transaction(); 1143 1144 message_send($message); 1145 $this->assertDebuggingNotCalled(); 1146 1147 $transaction2 = $DB->start_delegated_transaction(); 1148 1149 message_send($message); 1150 $this->assertDebuggingNotCalled(); 1151 1152 $DB->force_transaction_rollback(); 1153 $this->assertFalse($DB->is_transaction_started()); 1154 $this->assertDebuggingNotCalled(); 1155 1156 message_send($message); 1157 $this->assertDebuggingCalled('Not sending email due to $CFG->noemailever config setting'); 1158 } 1159 1160 public function test_message_attachment_send() { 1161 global $CFG; 1162 $this->preventResetByRollback(); 1163 $this->resetAfterTest(); 1164 1165 // Set config setting to allow attachments. 1166 $CFG->allowattachments = true; 1167 unset_config('noemailever'); 1168 1169 $user = $this->getDataGenerator()->create_user(); 1170 $context = \context_user::instance($user->id); 1171 1172 // Create a test file. 1173 $fs = get_file_storage(); 1174 $filerecord = array( 1175 'contextid' => $context->id, 1176 'component' => 'core', 1177 'filearea' => 'unittest', 1178 'itemid' => 99999, 1179 'filepath' => '/', 1180 'filename' => 'emailtest.txt' 1181 ); 1182 $file = $fs->create_file_from_string($filerecord, 'Test content'); 1183 1184 $message = new \core\message\message(); 1185 $message->courseid = 1; 1186 $message->component = 'moodle'; 1187 $message->name = 'instantmessage'; 1188 $message->userfrom = get_admin(); 1189 $message->userto = $user; 1190 $message->subject = 'message subject 1'; 1191 $message->fullmessage = 'message body'; 1192 $message->fullmessageformat = FORMAT_MARKDOWN; 1193 $message->fullmessagehtml = '<p>message body</p>'; 1194 $message->smallmessage = 'small message'; 1195 $message->attachment = $file; 1196 $message->attachname = 'emailtest.txt'; 1197 $message->notification = 0; 1198 1199 // Make sure we are redirecting emails. 1200 $sink = $this->redirectEmails(); 1201 message_send($message); 1202 1203 // Get the email that we just sent. 1204 $emails = $sink->get_messages(); 1205 $email = reset($emails); 1206 $this->assertTrue(strpos($email->body, 'Content-Disposition: attachment;') !== false); 1207 $this->assertTrue(strpos($email->body, 'emailtest.txt') !== false); 1208 1209 // Check if the stored file still exists after remove the temporary attachment. 1210 $storedfileexists = $fs->file_exists($filerecord['contextid'], $filerecord['component'], $filerecord['filearea'], 1211 $filerecord['itemid'], $filerecord['filepath'], $filerecord['filename']); 1212 $this->assertTrue($storedfileexists); 1213 } 1214 1215 public function test_send_message_when_muted() { 1216 $this->preventResetByRollback(); 1217 $this->resetAfterTest(); 1218 1219 $userfrom = $this->getDataGenerator()->create_user(); 1220 $userto = $this->getDataGenerator()->create_user(); 1221 1222 // Create a conversation between the users. 1223 $conversation = \core_message\api::create_conversation( 1224 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1225 [ 1226 $userfrom->id, 1227 $userto->id 1228 ] 1229 ); 1230 1231 $message = new \core\message\message(); 1232 $message->courseid = 1; 1233 $message->component = 'moodle'; 1234 $message->name = 'instantmessage'; 1235 $message->userfrom = $userfrom; 1236 $message->convid = $conversation->id; 1237 $message->subject = 'message subject 1'; 1238 $message->fullmessage = 'message body'; 1239 $message->fullmessageformat = FORMAT_MARKDOWN; 1240 $message->fullmessagehtml = '<p>message body</p>'; 1241 $message->smallmessage = 'small message'; 1242 $message->notification = '0'; 1243 1244 $sink = $this->redirectEmails(); 1245 message_send($message); 1246 $emails = $sink->get_messages(); 1247 $this->assertCount(1, $emails); 1248 $sink->clear(); 1249 1250 // Mute the conversation. 1251 \core_message\api::mute_conversation($userto->id, $conversation->id); 1252 1253 $sink = $this->redirectEmails(); 1254 message_send($message); 1255 $emails = $sink->get_messages(); 1256 $this->assertCount(0, $emails); 1257 $sink->clear(); 1258 } 1259 1260 /** 1261 * Is a particular message type in the list of message types. 1262 * @param string $component 1263 * @param string $name a message name. 1264 * @param array $providers as returned by message_get_providers_for_user. 1265 * @return bool whether the message type is present. 1266 */ 1267 protected function message_type_present($component, $name, $providers) { 1268 foreach ($providers as $provider) { 1269 if ($provider->component == $component && $provider->name == $name) { 1270 return true; 1271 } 1272 } 1273 return false; 1274 } 1275 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body