skip)) { continue; } if (is_subclass_of($class, 'CRM_Core_Page_Basic')) { $this->basicPages[] = $class; } } parent::setUp(); } /** * Make sure form hooks are only invoked once. */ public function testFormsCallBuildFormOnce() { CRM_Utils_Hook_UnitTests::singleton()->setHook('civicrm_buildForm', [$this, 'onBuildForm']); CRM_Utils_Hook_UnitTests::singleton()->setHook('civicrm_preProcess', [$this, 'onPreProcess']); $_REQUEST = ['action' => 'add']; foreach ($this->basicPages as $pageName) { // Reset the counters $this->hookCount = [ 'buildForm' => [], 'preProcess' => [], ]; $page = new $pageName(); ob_start(); $page->run(); ob_end_clean(); $this->runTestAssert($pageName); } } /** * Go through the record of hook invocation and make sure that each hook has * run once and no more than once per class. * * @param string $pageName * The page/form evaluated. */ private function runTestAssert($pageName) { foreach ($this->hookCount as $hook => $hookUsage) { $ran = FALSE; foreach ($hookUsage as $class => $count) { $ran = TRUE; // The hook should have run once and only once. $this->assertEquals(1, $count, "Checking $pageName: $hook invoked multiple times with $class"); } $this->assertTrue($ran, "$hook never invoked for $pageName"); } } /** * Make sure pageRun hook is only invoked once. */ public function testPagesCallPageRunOnce() { CRM_Utils_Hook_UnitTests::singleton()->setHook('civicrm_pageRun', [$this, 'onPageRun']); $_REQUEST = ['action' => 'browse']; foreach ($this->basicPages as $pageName) { // Reset the counters $this->hookCount = ['pageRun' => []]; $page = new $pageName(); ob_start(); $page->run(); ob_end_clean(); $this->runTestAssert($pageName); } } /** * Implements hook_civicrm_buildForm(). * * Increment the count of uses of this hook per formName. */ public function onBuildForm($formName, &$form) { $this->incrementHookCount('buildForm', $formName); } public function onPreProcess($formName, &$form) { $this->incrementHookCount('preProcess', $formName); } /** * Implements hook_civicrm_pageRun(). * * Increment the count of uses of this hook per page class. */ public function onPageRun(&$page) { $this->incrementHookCount('pageRun', get_class($page)); } /** * Increment the count of uses of a hook in a class. * * @param string $hook * The hook being used. * @param string $class * The class name of the page or form. */ private function incrementHookCount($hook, $class) { if (empty($this->hookCount[$hook][$class])) { $this->hookCount[$hook][$class] = 0; } $this->hookCount[$hook][$class]++; } }