| 1 | <?php |
| 2 | namespace Civi\Core\Event; |
| 3 | |
| 4 | class GenericHookEventTest extends \CiviUnitTestCase { |
| 5 | |
| 6 | public function tearDown(): void { |
| 7 | \CRM_Utils_Hook::singleton()->reset(); |
| 8 | parent::tearDown(); |
| 9 | } |
| 10 | |
| 11 | public function testConstructParams() { |
| 12 | $event = GenericHookEvent::create([ |
| 13 | 'ab' => 123, |
| 14 | 'cd' => ['foo' => 'bar'], |
| 15 | 'nothingNull' => NULL, |
| 16 | 'nothingZero' => 0, |
| 17 | ]); |
| 18 | $this->assertEquals(123, $event->ab); |
| 19 | $this->assertEquals('bar', $event->cd['foo']); |
| 20 | $this->assertTrue($event->hasField('ab')); |
| 21 | $this->assertTrue(isset($event->ab)); |
| 22 | $this->assertFalse($event->hasField('abc')); |
| 23 | $this->assertFalse(isset($event->abc)); |
| 24 | $this->assertTrue(!isset($event->nothingNull) && empty($event->nothingNull)); |
| 25 | $this->assertTrue(isset($event->nothingZero) && empty($event->nothingZero)); |
| 26 | } |
| 27 | |
| 28 | public function testConstructOrdered() { |
| 29 | $event = GenericHookEvent::createOrdered( |
| 30 | ['alpha', 'beta', 'nothingNull', 'nothingZero'], |
| 31 | [456, ['whiz' => 'bang'], NULL, 0, \CRM_Utils_Hook::$_nullObject] |
| 32 | ); |
| 33 | $this->assertEquals(456, $event->alpha); |
| 34 | $this->assertEquals('bang', $event->beta['whiz']); |
| 35 | $this->assertTrue($event->hasField('alpha')); |
| 36 | $this->assertTrue(isset($event->alpha)); |
| 37 | $this->assertFalse($event->hasField('ab')); |
| 38 | $this->assertFalse(isset($event->ab)); |
| 39 | $this->assertTrue(!isset($event->nothingNull) && empty($event->nothingNull)); |
| 40 | $this->assertTrue(isset($event->nothingZero) && empty($event->nothingZero)); |
| 41 | $this->assertEquals(4, count($event->getHookValues())); |
| 42 | } |
| 43 | |
| 44 | public function testDispatch() { |
| 45 | \CRM_Utils_Hook::singleton()->setHook('civicrm_ghet', |
| 46 | [$this, 'hook_civicrm_ghet']); |
| 47 | \Civi::dispatcher()->addListener('hook_civicrm_ghet', |
| 48 | [$this, 'onGhet']); |
| 49 | |
| 50 | $roString = 'readonly'; |
| 51 | $rwString = 'readwrite'; |
| 52 | $roArray = ['readonly']; |
| 53 | $rwArray = ['readwrite']; |
| 54 | $plainObj = new \stdClass(); |
| 55 | $refObj = new \stdClass(); |
| 56 | |
| 57 | $returnValue = $this->hookStub($roString, $rwString, $roArray, $rwArray, $plainObj, $refObj); |
| 58 | |
| 59 | $this->assertEquals('readonly', $roString); |
| 60 | $this->assertEquals('readwrite added-string-via-event added-string-via-hook', $rwString); |
| 61 | $this->assertEquals(['readonly'], $roArray); |
| 62 | $this->assertEquals(['readwrite', 'added-to-array-via-event', 'added-to-array-via-hook'], $rwArray); |
| 63 | $this->assertEquals('added-to-object-via-hook', $plainObj->prop1); |
| 64 | $this->assertEquals('added-to-object-via-hook', $refObj->prop2); |
| 65 | $this->assertEquals(['early-running-result', 'late-running-result'], $returnValue); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * Fire a hook. This stub follows the same coding convention as |
| 70 | * CRM_Utils_Hook::*(). This ensures that the coding convention is valid. |
| 71 | * |
| 72 | * @param $roString |
| 73 | * @param $rwString |
| 74 | * @param $roArray |
| 75 | * @param $rwArray |
| 76 | * @param $plainObj |
| 77 | * @param $refObj |
| 78 | * @return mixed |
| 79 | */ |
| 80 | public function hookStub($roString, &$rwString, $roArray, &$rwArray, $plainObj, &$refObj) { |
| 81 | return \CRM_Utils_Hook::singleton()->invoke( |
| 82 | ['roString', 'rwString', 'roArray', 'rwArray', 'plainObj', 'refObj'], |
| 83 | $roString, $rwString, $roArray, $rwArray, $plainObj, $refObj, |
| 84 | 'civicrm_ghet' |
| 85 | ); |
| 86 | } |
| 87 | |
| 88 | public function hook_civicrm_ghet(&$roString, &$rwString, &$roArray, &$rwArray, $plainObj, &$refObj) { |
| 89 | $roString .= 'changes should not propagate back'; |
| 90 | $rwString .= ' added-string-via-hook'; |
| 91 | $roArray[] = 'changes should not propagate back'; |
| 92 | $rwArray[] = 'added-to-array-via-hook'; |
| 93 | $plainObj->prop1 = 'added-to-object-via-hook'; |
| 94 | $refObj->prop2 = 'added-to-object-via-hook'; |
| 95 | return ['late-running-result']; |
| 96 | } |
| 97 | |
| 98 | public function onGhet(GenericHookEvent $e) { |
| 99 | $e->roString .= 'changes should not propagate back'; |
| 100 | $e->rwString .= ' added-string-via-event'; |
| 101 | $e->roArray[] = 'changes should not propagate back'; |
| 102 | $e->rwArray[] = 'added-to-array-via-event'; |
| 103 | $e->plainObj->prop1 = 'added-to-object-via-event'; |
| 104 | $e->refObj->prop2 = 'added-to-object-via-event'; |
| 105 | $e->addReturnValues(['early-running-result']); |
| 106 | } |
| 107 | |
| 108 | } |