See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310]
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 * Tests for event manager, base event and observers. 19 * 20 * @package core 21 * @category phpunit 22 * @copyright 2013 Petr Skoda {@link http://skodak.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once (__DIR__.'/fixtures/event_fixtures.php'); 29 30 class core_event_testcase extends advanced_testcase { 31 32 const DEBUGGING_MSG = 'Events API using $handlers array has been deprecated in favour of Events 2 API, please use it instead.'; 33 34 public function test_event_properties() { 35 global $USER; 36 37 $system = \context_system::instance(); 38 $event = \core_tests\event\unittest_executed::create(array('context'=>$system, 'objectid'=>5, 'other'=>array('sample'=>null, 'xx'=>10))); 39 40 $this->assertSame('\core_tests\event\unittest_executed', $event->eventname); 41 $this->assertSame('core_tests', $event->component); 42 $this->assertSame('executed', $event->action); 43 $this->assertSame('unittest', $event->target); 44 $this->assertSame(5, $event->objectid); 45 $this->assertSame('u', $event->crud); 46 $this->assertSame(\core\event\base::LEVEL_PARTICIPATING, $event->edulevel); 47 48 $this->assertEquals($system, $event->get_context()); 49 $this->assertSame($system->id, $event->contextid); 50 $this->assertSame($system->contextlevel, $event->contextlevel); 51 $this->assertSame($system->instanceid, $event->contextinstanceid); 52 53 $this->assertSame($USER->id, $event->userid); 54 $this->assertSame(0, $event->courseid); 55 56 $this->assertNull($event->relateduserid); 57 $this->assertFalse(isset($event->relateduserid)); 58 59 $this->assertSame(0, $event->anonymous); 60 61 $this->assertSame(array('sample'=>null, 'xx'=>10), $event->other); 62 $this->assertTrue(isset($event->other['xx'])); 63 $this->assertFalse(isset($event->other['sample'])); 64 65 $this->assertLessThanOrEqual(time(), $event->timecreated); 66 67 try { 68 $event->courseid = 2; 69 $this->fail('Exception expected on event modification'); 70 } catch (\moodle_exception $e) { 71 $this->assertInstanceOf('coding_exception', $e); 72 } 73 74 try { 75 $event->xxxx = 1; 76 $this->fail('Exception expected on event modification'); 77 } catch (\moodle_exception $e) { 78 $this->assertInstanceOf('coding_exception', $e); 79 } 80 81 $event2 = \core_tests\event\unittest_executed::create(array('contextid'=>$system->id, 'objectid'=>5, 'anonymous'=>1, 'other'=>array('sample'=>null, 'xx'=>10))); 82 $this->assertEquals($event->get_context(), $event2->get_context()); 83 $this->assertSame(1, $event2->anonymous); 84 85 $event3 = \core_tests\event\unittest_executed::create(array('contextid'=>$system->id, 'objectid'=>5, 'anonymous'=>true, 'other'=>array('sample'=>null, 'xx'=>10))); 86 $this->assertSame(1, $event3->anonymous); 87 } 88 89 public function test_event_properties_guessing() { 90 global $USER; 91 $this->resetAfterTest(); 92 93 $course = $this->getDataGenerator()->create_course(); 94 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 95 $context = context_module::instance($forum->cmid); 96 $event = \core_tests\event\unittest_executed::create(array('context' => $context, 'objectid' => 5)); 97 98 // Check guessed course ID, and default properties. 99 $this->assertSame('\core_tests\event\unittest_executed', $event->eventname); 100 $this->assertSame('core_tests', $event->component); 101 $this->assertSame('executed', $event->action); 102 $this->assertSame('unittest', $event->target); 103 $this->assertSame(5, $event->objectid); 104 $this->assertEquals($context, $event->get_context()); 105 $this->assertEquals($course->id, $event->courseid); 106 $this->assertSame($USER->id, $event->userid); 107 $this->assertNull($event->relateduserid); 108 109 $user = $this->getDataGenerator()->create_user(); 110 $context = context_user::instance($user->id); 111 $event = \core_tests\event\unittest_executed::create(array('contextid' => $context->id, 'objectid' => 5)); 112 113 // Check guessing on contextid, and user context level. 114 $this->assertEquals($context, $event->get_context()); 115 $this->assertEquals($context->id, $event->contextid); 116 $this->assertEquals($context->contextlevel, $event->contextlevel); 117 $this->assertSame(0, $event->courseid); 118 $this->assertSame($USER->id, $event->userid); 119 $this->assertSame($user->id, $event->relateduserid); 120 } 121 122 public function test_observers_parsing() { 123 global $CFG; 124 125 $observers = array( 126 array( 127 'eventname' => '*', 128 'callback' => array('\core_tests\event\unittest_observer', 'observe_all_alt'), 129 ), 130 array( 131 'eventname' => '\core_tests\event\unittest_executed', 132 'callback' => '\core_tests\event\unittest_observer::observe_one', 133 'includefile' => 'lib/tests/fixtures/event_fixtures.php', 134 ), 135 array( 136 'eventname' => '*', 137 'callback' => array('\core_tests\event\unittest_observer', 'observe_all'), 138 'includefile' => null, 139 'internal' => 1, 140 'priority' => 10, 141 ), 142 array( 143 'eventname' => '\core\event\unknown_executed', 144 'callback' => '\core_tests\event\unittest_observer::broken_observer', 145 'priority' => 100, 146 ), 147 array( 148 'eventname' => '\core_tests\event\unittest_executed', 149 'callback' => '\core_tests\event\unittest_observer::external_observer', 150 'priority' => 200, 151 'internal' => 0, 152 ), 153 ); 154 155 $result = \core\event\manager::phpunit_replace_observers($observers); 156 $this->assertCount(3, $result); 157 158 $expected = array(); 159 $observer = new stdClass(); 160 $observer->callable = '\core_tests\event\unittest_observer::external_observer'; 161 $observer->priority = 200; 162 $observer->internal = false; 163 $observer->includefile = null; 164 $observer->plugintype = null; 165 $observer->plugin = null; 166 $expected[0] = $observer; 167 $observer = new stdClass(); 168 $observer->callable = '\core_tests\event\unittest_observer::observe_one'; 169 $observer->priority = 0; 170 $observer->internal = true; 171 $observer->includefile = $CFG->dirroot.'/lib/tests/fixtures/event_fixtures.php'; 172 $observer->plugintype = null; 173 $observer->plugin = null; 174 $expected[1] = $observer; 175 176 $this->assertEquals($expected, $result['\core_tests\event\unittest_executed']); 177 178 $expected = array(); 179 $observer = new stdClass(); 180 $observer->callable = '\core_tests\event\unittest_observer::broken_observer'; 181 $observer->priority = 100; 182 $observer->internal = true; 183 $observer->includefile = null; 184 $observer->plugintype = null; 185 $observer->plugin = null; 186 $expected[0] = $observer; 187 188 $this->assertEquals($expected, $result['\core\event\unknown_executed']); 189 190 $expected = array(); 191 $observer = new stdClass(); 192 $observer->callable = array('\core_tests\event\unittest_observer', 'observe_all'); 193 $observer->priority = 10; 194 $observer->internal = true; 195 $observer->includefile = null; 196 $observer->plugintype = null; 197 $observer->plugin = null; 198 $expected[0] = $observer; 199 $observer = new stdClass(); 200 $observer->callable = array('\core_tests\event\unittest_observer', 'observe_all_alt'); 201 $observer->priority = 0; 202 $observer->internal = true; 203 $observer->includefile = null; 204 $observer->plugintype = null; 205 $observer->plugin = null; 206 $expected[1] = $observer; 207 208 $this->assertEquals($expected, $result['\core\event\base']); 209 210 // Now test broken stuff... 211 212 $observers = array( 213 array( 214 'eventname' => 'core_tests\event\unittest_executed', // Fix leading backslash. 215 'callback' => '\core_tests\event\unittest_observer::observe_one', 216 'includefile' => 'lib/tests/fixtures/event_fixtures.php', 217 'internal' => 1, // Cast to bool. 218 ), 219 ); 220 $result = \core\event\manager::phpunit_replace_observers($observers); 221 $this->assertCount(1, $result); 222 $expected = array(); 223 $observer = new stdClass(); 224 $observer->callable = '\core_tests\event\unittest_observer::observe_one'; 225 $observer->priority = 0; 226 $observer->internal = true; 227 $observer->includefile = $CFG->dirroot.'/lib/tests/fixtures/event_fixtures.php'; 228 $observer->plugintype = null; 229 $observer->plugin = null; 230 $expected[0] = $observer; 231 $this->assertEquals($expected, $result['\core_tests\event\unittest_executed']); 232 233 $observers = array( 234 array( 235 // Missing eventclass. 236 'callback' => '\core_tests\event\unittest_observer::observe_one', 237 'includefile' => 'lib/tests/fixtures/event_fixtures.php', 238 ), 239 ); 240 $result = \core\event\manager::phpunit_replace_observers($observers); 241 $this->assertCount(0, $result); 242 $this->assertDebuggingCalled(); 243 244 $observers = array( 245 array( 246 'eventname' => '', // Empty eventclass. 247 'callback' => '\core_tests\event\unittest_observer::observe_one', 248 'includefile' => 'lib/tests/fixtures/event_fixtures.php', 249 ), 250 ); 251 $result = \core\event\manager::phpunit_replace_observers($observers); 252 $this->assertCount(0, $result); 253 $this->assertDebuggingCalled(); 254 255 $observers = array( 256 array( 257 'eventname' => '\core_tests\event\unittest_executed', 258 // Missing callable. 259 'includefile' => 'lib/tests/fixtures/event_fixtures.php', 260 ), 261 ); 262 $result = \core\event\manager::phpunit_replace_observers($observers); 263 $this->assertCount(0, $result); 264 $this->assertDebuggingCalled(); 265 266 $observers = array( 267 array( 268 'eventname' => '\core_tests\event\unittest_executed', 269 'callback' => '', // Empty callable. 270 'includefile' => 'lib/tests/fixtures/event_fixtures.php', 271 ), 272 ); 273 $result = \core\event\manager::phpunit_replace_observers($observers); 274 $this->assertCount(0, $result); 275 $this->assertDebuggingCalled(); 276 277 $observers = array( 278 array( 279 'eventname' => '\core_tests\event\unittest_executed', 280 'callback' => '\core_tests\event\unittest_observer::observe_one', 281 'includefile' => 'lib/tests/fixtures/event_fixtures.php_xxx', // Missing file. 282 ), 283 ); 284 $result = \core\event\manager::phpunit_replace_observers($observers); 285 $this->assertCount(0, $result); 286 $this->assertDebuggingCalled(); 287 } 288 289 public function test_normal_dispatching() { 290 $observers = array( 291 array( 292 'eventname' => '\core_tests\event\unittest_executed', 293 'callback' => '\core_tests\event\unittest_observer::observe_one', 294 ), 295 array( 296 'eventname' => '*', 297 'callback' => '\core_tests\event\unittest_observer::observe_all', 298 'includefile' => null, 299 'internal' => 1, 300 'priority' => 9999, 301 ), 302 ); 303 304 \core\event\manager::phpunit_replace_observers($observers); 305 \core_tests\event\unittest_observer::reset(); 306 307 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 308 $event1->nest = 1; 309 $this->assertFalse($event1->is_triggered()); 310 $this->assertFalse($event1->is_dispatched()); 311 $this->assertFalse($event1->is_restored()); 312 $event1->trigger(); 313 $this->assertTrue($event1->is_triggered()); 314 $this->assertTrue($event1->is_dispatched()); 315 $this->assertFalse($event1->is_restored()); 316 317 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>2, 'xx'=>10))); 318 $event1->trigger(); 319 320 $this->assertSame( 321 array('observe_all-nesting-1', 'observe_one-1', 'observe_all-666', 'observe_one-666', 'observe_all-2', 'observe_one-2'), 322 \core_tests\event\unittest_observer::$info); 323 } 324 325 public function test_event_sink() { 326 $sink = $this->redirectEvents(); 327 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 328 $event1->trigger(); 329 $this->assertSame(1, $sink->count()); 330 $retult = $sink->get_events(); 331 $this->assertSame($event1, $retult[0]); 332 333 $event2 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>2, 'xx'=>10))); 334 $event2->trigger(); 335 $this->assertSame(2, $sink->count()); 336 $retult = $sink->get_events(); 337 $this->assertSame($event1, $retult[0]); 338 $this->assertSame($event2, $retult[1]); 339 340 $sink->clear(); 341 $this->assertSame(0, $sink->count()); 342 $this->assertSame(array(), $sink->get_events()); 343 344 $event3 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>3, 'xx'=>10))); 345 $event3->trigger(); 346 $this->assertSame(1, $sink->count()); 347 $retult = $sink->get_events(); 348 $this->assertSame($event3, $retult[0]); 349 350 $sink->close(); 351 $event4 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>4, 'xx'=>10))); 352 $event4->trigger(); 353 $this->assertSame(1, $sink->count()); 354 $retult = $sink->get_events(); 355 $this->assertSame($event3, $retult[0]); 356 } 357 358 public function test_ignore_exceptions() { 359 $observers = array( 360 361 array( 362 'eventname' => '\core_tests\event\unittest_executed', 363 'callback' => '\core_tests\event\unittest_observer::observe_one', 364 ), 365 366 array( 367 'eventname' => '\core_tests\event\unittest_executed', 368 'callback' => '\core_tests\event\unittest_observer::broken_observer', 369 'priority' => 100, 370 ), 371 ); 372 373 \core\event\manager::phpunit_replace_observers($observers); 374 \core_tests\event\unittest_observer::reset(); 375 376 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 377 $event1->trigger(); 378 $this->assertDebuggingCalled(); 379 380 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>2, 'xx'=>10))); 381 $event1->trigger(); 382 $this->assertDebuggingCalled(); 383 384 $this->assertSame( 385 array('broken_observer-1', 'observe_one-1', 'broken_observer-2', 'observe_one-2'), 386 \core_tests\event\unittest_observer::$info); 387 } 388 389 public function test_external_buffer() { 390 global $DB; 391 392 $this->preventResetByRollback(); 393 394 $observers = array( 395 396 array( 397 'eventname' => '\core_tests\event\unittest_executed', 398 'callback' => '\core_tests\event\unittest_observer::observe_one', 399 ), 400 401 array( 402 'eventname' => '\core_tests\event\unittest_executed', 403 'callback' => '\core_tests\event\unittest_observer::external_observer', 404 'priority' => 200, 405 'internal' => 0, 406 ), 407 ); 408 409 \core\event\manager::phpunit_replace_observers($observers); 410 \core_tests\event\unittest_observer::reset(); 411 412 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 413 $event1->trigger(); 414 $event2 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>2, 'xx'=>10))); 415 $event2->trigger(); 416 417 $this->assertSame( 418 array('external_observer-1', 'observe_one-1', 'external_observer-2', 'observe_one-2'), 419 \core_tests\event\unittest_observer::$info); 420 421 \core\event\manager::phpunit_replace_observers($observers); 422 \core_tests\event\unittest_observer::reset(); 423 424 $this->assertSame(array(), \core_tests\event\unittest_observer::$info); 425 426 $trans = $DB->start_delegated_transaction(); 427 428 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 429 $event1->trigger(); 430 $event2 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>2, 'xx'=>10))); 431 $event2->trigger(); 432 433 $this->assertSame( 434 array('observe_one-1', 'observe_one-2'), 435 \core_tests\event\unittest_observer::$info); 436 437 $trans->allow_commit(); 438 439 $this->assertSame( 440 array('observe_one-1', 'observe_one-2', 'external_observer-1', 'external_observer-2'), 441 \core_tests\event\unittest_observer::$info); 442 443 \core\event\manager::phpunit_replace_observers($observers); 444 \core_tests\event\unittest_observer::reset(); 445 446 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 447 $event1->trigger(); 448 $trans = $DB->start_delegated_transaction(); 449 $event2 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>2, 'xx'=>10))); 450 $event2->trigger(); 451 try { 452 $trans->rollback(new \moodle_exception('xxx')); 453 $this->fail('Expecting exception'); 454 } catch (\moodle_exception $e) { 455 $this->assertInstanceOf('moodle_exception', $e); 456 } 457 458 $this->assertSame( 459 array('external_observer-1', 'observe_one-1', 'observe_one-2'), 460 \core_tests\event\unittest_observer::$info); 461 } 462 463 public function test_rollback() { 464 global $DB; 465 466 $this->resetAfterTest(); 467 $this->preventResetByRollback(); 468 469 $observers = array( 470 array( 471 'eventname' => '\core_tests\event\unittest_executed', 472 'callback' => '\core_tests\event\unittest_observer::external_observer', 473 'internal' => 0, 474 ), 475 ); 476 477 \core\event\manager::phpunit_replace_observers($observers); 478 \core_tests\event\unittest_observer::reset(); 479 480 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 481 482 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 483 $this->assertCount(1, \core_tests\event\unittest_observer::$event); 484 \core_tests\event\unittest_observer::reset(); 485 486 $transaction1 = $DB->start_delegated_transaction(); 487 488 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 489 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 490 491 $transaction2 = $DB->start_delegated_transaction(); 492 493 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 494 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 495 496 try { 497 $transaction2->rollback(new Exception('x')); 498 $this->fail('Expecting exception'); 499 } catch (Exception $e) {} 500 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 501 502 $this->assertTrue($DB->is_transaction_started()); 503 504 try { 505 $transaction1->rollback(new Exception('x')); 506 $this->fail('Expecting exception'); 507 } catch (Exception $e) {} 508 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 509 510 $this->assertFalse($DB->is_transaction_started()); 511 512 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 513 $this->assertCount(1, \core_tests\event\unittest_observer::$event); 514 } 515 516 public function test_forced_rollback() { 517 global $DB; 518 519 $this->resetAfterTest(); 520 $this->preventResetByRollback(); 521 522 $observers = array( 523 array( 524 'eventname' => '\core_tests\event\unittest_executed', 525 'callback' => '\core_tests\event\unittest_observer::external_observer', 526 'internal' => 0, 527 ), 528 ); 529 530 \core\event\manager::phpunit_replace_observers($observers); 531 \core_tests\event\unittest_observer::reset(); 532 533 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 534 535 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 536 $this->assertCount(1, \core_tests\event\unittest_observer::$event); 537 \core_tests\event\unittest_observer::reset(); 538 539 $transaction1 = $DB->start_delegated_transaction(); 540 541 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 542 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 543 544 $transaction2 = $DB->start_delegated_transaction(); 545 546 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 547 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 548 549 $DB->force_transaction_rollback(); 550 $this->assertCount(0, \core_tests\event\unittest_observer::$event); 551 552 $this->assertFalse($DB->is_transaction_started()); 553 554 \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); 555 $this->assertCount(1, \core_tests\event\unittest_observer::$event); 556 } 557 558 public function test_deprecated() { 559 global $DB; 560 561 $this->resetAfterTest(true); 562 563 $event = \core_tests\event\deprecated_event1::create(); 564 $this->assertDebuggingCalled('level property is deprecated, use edulevel property instead'); 565 566 $this->assertSame($event::LEVEL_TEACHING, $event->level); 567 $this->assertDebuggingCalled('level property is deprecated, use edulevel property instead'); 568 569 $this->assertTrue(isset($event->level)); 570 $this->assertDebuggingCalled('level property is deprecated, use edulevel property instead'); 571 572 $this->assertSame($event::LEVEL_TEACHING, $event->edulevel); 573 } 574 575 public function test_legacy() { 576 global $DB, $CFG; 577 578 $this->resetAfterTest(true); 579 580 $observers = array( 581 array( 582 'eventname' => '\core_tests\event\unittest_executed', 583 'callback' => '\core_tests\event\unittest_observer::observe_one', 584 ), 585 array( 586 'eventname' => '*', 587 'callback' => '\core_tests\event\unittest_observer::observe_all', 588 'includefile' => null, 589 'internal' => 1, 590 'priority' => 9999, 591 ), 592 ); 593 594 $DB->delete_records('log', array()); 595 $this->expectException('coding_exception'); 596 events_update_definition('unittest'); 597 598 $DB->delete_records_select('events_handlers', "component <> 'unittest'"); 599 events_get_handlers('reset'); 600 $this->assertDebuggingCalled(self::DEBUGGING_MSG, DEBUG_DEVELOPER); 601 $this->assertEquals(3, $DB->count_records('events_handlers')); 602 set_config('loglifetime', 60*60*24*5); 603 604 \core\event\manager::phpunit_replace_observers($observers); 605 \core_tests\event\unittest_observer::reset(); 606 607 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>5, 'xx'=>10))); 608 $event1->trigger(); 609 610 $event2 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>6, 'xx'=>11))); 611 $event2->nest = true; 612 $event2->trigger(); 613 614 $this->assertSame( 615 array('observe_all-5', 'observe_one-5', 'observe_all-nesting-6', 'observe_one-6', 'observe_all-666', 'observe_one-666'), 616 \core_tests\event\unittest_observer::$info); 617 618 $this->assertSame($event1, \core_tests\event\unittest_observer::$event[0]); 619 $this->assertSame($event1, \core_tests\event\unittest_observer::$event[1]); 620 621 $logs = $DB->get_records('log', array(), 'id ASC'); 622 $this->assertCount(0, $logs); 623 } 624 625 public function test_restore_event() { 626 $event1 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 627 $data1 = $event1->get_data(); 628 629 $event2 = \core\event\base::restore($data1, array('origin'=>'clid')); 630 $data2 = $event2->get_data(); 631 632 $this->assertTrue($event2->is_triggered()); 633 $this->assertTrue($event2->is_restored()); 634 $this->assertEquals($data1, $data2); 635 $this->assertInstanceOf('core_tests\event\unittest_executed', $event2); 636 637 $this->assertEquals($event1->get_context(), $event2->get_context()); 638 639 // Now test problematic data. 640 $data3 = $data1; 641 $data3['eventname'] = '\\a\\b\\c'; 642 $event3 = \core\event\base::restore($data3, array()); 643 $this->assertFalse($event3, 'Class name must match'); 644 645 $data4 = $data1; 646 unset($data4['userid']); 647 $event4 = \core\event\base::restore($data4, array()); 648 $this->assertInstanceOf('core_tests\event\unittest_executed', $event4); 649 $this->assertDebuggingCalled(); 650 651 $data5 = $data1; 652 $data5['xx'] = 'xx'; 653 $event5 = \core\event\base::restore($data5, array()); 654 $this->assertInstanceOf('core_tests\event\unittest_executed', $event5); 655 $this->assertDebuggingCalled(); 656 657 } 658 659 public function test_trigger_problems() { 660 $this->resetAfterTest(true); 661 662 $event = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>5, 'xx'=>10))); 663 $event->trigger(); 664 try { 665 $event->trigger(); 666 $this->fail('Exception expected on double trigger'); 667 } catch (\moodle_exception $e) { 668 $this->assertInstanceOf('coding_exception', $e); 669 } 670 671 $data = $event->get_data(); 672 $restored = \core_tests\event\unittest_executed::restore($data, array()); 673 $this->assertTrue($restored->is_triggered()); 674 $this->assertTrue($restored->is_restored()); 675 676 try { 677 $restored->trigger(); 678 $this->fail('Exception expected on triggering of restored event'); 679 } catch (\moodle_exception $e) { 680 $this->assertInstanceOf('coding_exception', $e); 681 } 682 683 $event = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>5, 'xx'=>10))); 684 try { 685 \core\event\manager::dispatch($event); 686 $this->fail('Exception expected on manual event dispatching'); 687 } catch (\moodle_exception $e) { 688 $this->assertInstanceOf('coding_exception', $e); 689 } 690 } 691 692 public function test_bad_events() { 693 $this->resetAfterTest(true); 694 695 try { 696 $event = \core_tests\event\unittest_executed::create(array('other'=>array('sample'=>5, 'xx'=>10))); 697 $this->fail('Exception expected when context and contextid missing'); 698 } catch (\moodle_exception $e) { 699 $this->assertInstanceOf('coding_exception', $e); 700 } 701 702 $event = \core_tests\event\bad_event1::create(array('context'=>\context_system::instance())); 703 try { 704 $event->trigger(); 705 $this->fail('Exception expected when $data not valid'); 706 } catch (\moodle_exception $e) { 707 $this->assertInstanceOf('\coding_exception', $e); 708 } 709 710 $event = \core_tests\event\bad_event2::create(array('context'=>\context_system::instance())); 711 try { 712 $event->trigger(); 713 $this->fail('Exception expected when $data not valid'); 714 } catch (\moodle_exception $e) { 715 $this->assertInstanceOf('\coding_exception', $e); 716 } 717 718 $event = \core_tests\event\bad_event2b::create(array('context'=>\context_system::instance())); 719 @$event->trigger(); 720 $this->assertDebuggingCalled(); 721 722 $event = \core_tests\event\bad_event3::create(array('context'=>\context_system::instance())); 723 @$event->trigger(); 724 $this->assertDebuggingCalled(); 725 726 $event = \core_tests\event\bad_event4::create(array('context'=>\context_system::instance())); 727 @$event->trigger(); 728 $this->assertDebuggingCalled(); 729 730 $event = \core_tests\event\bad_event5::create(array('context'=>\context_system::instance())); 731 @$event->trigger(); 732 $this->assertDebuggingCalled(); 733 734 $event = \core_tests\event\bad_event6::create(array('objectid'=>1, 'context'=>\context_system::instance())); 735 $event->trigger(); 736 $this->assertDebuggingCalled('Unknown table specified in objecttable field'); 737 738 $event = \core_tests\event\bad_event7::create(array('objectid'=>1, 'context'=>\context_system::instance())); 739 try { 740 $event->trigger(); 741 $this->fail('Exception expected when $data contains objectid but objecttable not specified'); 742 } catch (\moodle_exception $e) { 743 $this->assertInstanceOf('\coding_exception', $e); 744 } 745 746 $event = \core_tests\event\bad_event8::create(array('context'=>\context_system::instance())); 747 $event->trigger(); 748 $this->assertDebuggingCalled('Event property objectid must be set when objecttable is defined'); 749 } 750 751 public function test_problematic_events() { 752 $this->resetAfterTest(true); 753 754 $event1 = \core_tests\event\problematic_event1::create(array('context'=>\context_system::instance())); 755 $this->assertDebuggingNotCalled(); 756 $this->assertNull($event1->xxx); 757 $this->assertDebuggingCalled(); 758 759 $event2 = \core_tests\event\problematic_event1::create(array('xxx'=>0, 'context'=>\context_system::instance())); 760 $this->assertDebuggingCalled(); 761 762 set_debugging(DEBUG_NONE); 763 $event3 = \core_tests\event\problematic_event1::create(array('xxx'=>0, 'context'=>\context_system::instance())); 764 $this->assertDebuggingNotCalled(); 765 set_debugging(DEBUG_DEVELOPER); 766 767 $event4 = \core_tests\event\problematic_event1::create(array('context'=>\context_system::instance(), 'other'=>array('a'=>1))); 768 $event4->trigger(); 769 $this->assertDebuggingNotCalled(); 770 771 $event5 = \core_tests\event\problematic_event1::create(array('context'=>\context_system::instance(), 'other'=>(object)array('a'=>1))); 772 $this->assertDebuggingNotCalled(); 773 $event5->trigger(); 774 $this->assertDebuggingCalled(); 775 776 $url = new moodle_url('/admin/'); 777 $event6 = \core_tests\event\problematic_event1::create(array('context'=>\context_system::instance(), 'other'=>array('a'=>$url))); 778 $this->assertDebuggingNotCalled(); 779 $event6->trigger(); 780 $this->assertDebuggingCalled(); 781 782 // Check that whole float numbers do not trigger debugging messages. 783 $event7 = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 784 'other' => array('wholenumber' => 90.0000, 'numberwithdecimals' => 54.7656, 'sample' => 1))); 785 $event7->trigger(); 786 $this->assertDebuggingNotCalled(); 787 788 $event = \core_tests\event\problematic_event2::create(array()); 789 $this->assertDebuggingNotCalled(); 790 $event = \core_tests\event\problematic_event2::create(array('context'=>\context_system::instance())); 791 $this->assertDebuggingCalled(); 792 793 $event = \core_tests\event\problematic_event3::create(array('other'=>1)); 794 $this->assertDebuggingNotCalled(); 795 $event = \core_tests\event\problematic_event3::create(array()); 796 $this->assertDebuggingCalled(); 797 } 798 799 public function test_record_snapshots() { 800 global $DB; 801 802 $this->resetAfterTest(true); 803 804 $event = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 805 $course1 = $DB->get_record('course', array('id'=>1)); 806 $this->assertNotEmpty($course1); 807 808 $event->add_record_snapshot('course', $course1); 809 810 $result = $event->get_record_snapshot('course', $course1->id); 811 // Convert to arrays because record snapshot returns a clone of the object. 812 $this->assertSame((array)$course1, (array)$result); 813 814 $user = $event->get_record_snapshot('user', 1); 815 $this->assertEquals(1, $user->id); 816 $this->assertSame('guest', $user->username); 817 818 $event->add_record_snapshot('course', $course1); 819 $event->trigger(); 820 try { 821 $event->add_record_snapshot('course', $course1); 822 $this->fail('Updating of snapshots after trigger is not ok');; 823 } catch (\moodle_exception $e) { 824 $this->assertInstanceOf('\coding_exception', $e); 825 } 826 827 $event2 = \core_tests\event\unittest_executed::restore($event->get_data(), array()); 828 try { 829 $event2->get_record_snapshot('course', $course1->id); 830 $this->fail('Reading of snapshots from restored events is not ok');; 831 } catch (\moodle_exception $e) { 832 $this->assertInstanceOf('\coding_exception', $e); 833 } 834 } 835 836 public function test_get_name() { 837 $event = \core_tests\event\noname_event::create(array('other' => array('sample' => 1, 'xx' => 10))); 838 $this->assertEquals("core_tests: noname event", $event->get_name()); 839 } 840 841 public function test_iteration() { 842 $event = \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10))); 843 844 $data = array(); 845 foreach ($event as $k => $v) { 846 $data[$k] = $v; 847 } 848 849 $this->assertSame($event->get_data(), $data); 850 } 851 852 /** 853 * @expectedException PHPUnit\Framework\Error\Notice 854 */ 855 public function test_context_not_used() { 856 $event = \core_tests\event\context_used_in_event::create(array('other' => array('sample' => 1, 'xx' => 10))); 857 $this->assertEventContextNotUsed($event); 858 859 $eventcontext = phpunit_event_mock::testable_get_event_context($event); 860 phpunit_event_mock::testable_set_event_context($event, null); 861 $this->assertEventContextNotUsed($event); 862 } 863 864 /** 865 * Test that all observer information is returned correctly. 866 */ 867 public function test_get_all_observers() { 868 // Retrieve all observers. 869 $observers = \core\event\manager::get_all_observers(); 870 871 // Expected information from the workshop allocation scheduled observer. 872 $expected = new stdClass(); 873 $expected->callable = '\workshopallocation_scheduled\observer::workshop_viewed'; 874 $expected->priority = 0; 875 $expected->internal = true; 876 $expected->includefile = null; 877 $expected->plugintype = 'workshopallocation'; 878 $expected->plugin = 'scheduled'; 879 880 // May be more than one observer for the mod_workshop event. 881 $found = false; 882 foreach ($observers['\mod_workshop\event\course_module_viewed'] as $observer) { 883 if ($expected == $observer) { 884 $found = true; 885 break; 886 } 887 } 888 $this->assertTrue($found); 889 } 890 891 /** 892 * Test formatting of the get_explanation method. 893 * This formats the information from an events class docblock. 894 */ 895 public function test_get_explanation() { 896 $explanation = \core_tests\event\full_docblock::get_explanation(); 897 898 $expected = "This is an explanation of the event. 899 - I'm making a point here. 900 - I have a second {@link something} point here. 901 - whitespace is intentional to test it's removal. 902 I have something else *Yeah* that."; 903 904 $this->assertEquals($explanation, $expected); 905 906 $explanation = \core_tests\event\docblock_test2::get_explanation(); 907 908 $expected = "We have only the description in the docblock 909 and nothing else."; 910 911 $this->assertEquals($explanation, $expected); 912 913 $explanation = \core_tests\event\docblock_test3::get_explanation(); 914 $expected = "Calendar event created event."; 915 $this->assertEquals($explanation, $expected); 916 917 } 918 919 /** 920 * Test that general information about an event is returned 921 * by the get_static_info() method. 922 */ 923 public function test_get_static_info() { 924 $staticinfo = \core_tests\event\static_info_viewing::get_static_info(); 925 926 $expected = array( 927 'eventname' => '\\core_tests\\event\\static_info_viewing', 928 'component' => 'core_tests', 929 'target' => 'static_info', 930 'action' => 'viewing', 931 'crud' => 'r', 932 'edulevel' => 0, 933 'objecttable' => 'mod_unittest' 934 ); 935 $this->assertEquals($staticinfo, $expected); 936 } 937 938 /** 939 * This tests the internal method of \core\event\manager::get_observing_classes. 940 * 941 * What we are testing is if we can subscribe to a parent event class, instead of only 942 * the base event class or the final, implemented event class. This enables us to subscribe 943 * to things like all course module view events, all comment created events, etc. 944 */ 945 public function test_observe_parent_event() { 946 $this->resetAfterTest(); 947 948 // Ensure this has been reset prior to using it. 949 \core_tests\event\unittest_observer::reset(); 950 951 $course = $this->getDataGenerator()->create_course(); 952 $feed = $this->getDataGenerator()->create_module('feedback', ['course' => $course->id]); 953 $context = context_module::instance($feed->cmid); 954 $data = [ 955 'context' => $context, 956 'courseid' => $course->id, 957 'objectid' => $feed->id 958 ]; 959 960 // This assertion ensures that basic observe use case did not break. 961 \core\event\manager::phpunit_replace_observers([[ 962 'eventname' => '\core_tests\event\course_module_viewed', 963 'callback' => ['\core_tests\event\unittest_observer', 'observe_all_alt'], 964 ]]); 965 966 $pageevent = \core_tests\event\course_module_viewed::create($data); 967 $pageevent->trigger(); 968 969 $this->assertSame(['observe_all_alt'], \core_tests\event\unittest_observer::$info, 'Error observing triggered event'); 970 971 \core_tests\event\unittest_observer::reset(); 972 973 // This assertion tests that we can observe an abstract (parent) class instead of the implemented class. 974 \core\event\manager::phpunit_replace_observers([[ 975 'eventname' => '\core\event\course_module_viewed', 976 'callback' => ['\core_tests\event\unittest_observer', 'observe_all_alt'], 977 ]]); 978 979 $pageevent = \core_tests\event\course_module_viewed::create($data); 980 $pageevent->trigger(); 981 982 $this->assertSame(['observe_all_alt'], \core_tests\event\unittest_observer::$info, 'Error observing parent class event'); 983 984 \core_tests\event\unittest_observer::reset(); 985 } 986 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body