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