From 076d8c821aea161a96d36779edfcf8e221d57124 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 14 Nov 2013 17:02:16 -0800 Subject: [PATCH] CRM-13768 - api_v3_SettingTest, CRM_Core_BAO_SettingTest - Test for on_change event ---------------------------------------- * CRM-13768: CiviCase not fully activated during extension installation http://issues.civicrm.org/jira/browse/CRM-13768 --- tests/phpunit/CRM/Core/BAO/SettingTest.php | 69 +++++++++++++++++++++ tests/phpunit/CiviTest/CiviUnitTestCase.php | 24 +++++++ tests/phpunit/api/v3/SettingTest.php | 66 ++++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/tests/phpunit/CRM/Core/BAO/SettingTest.php b/tests/phpunit/CRM/Core/BAO/SettingTest.php index 0943c5a2d2..c9c9086ee7 100644 --- a/tests/phpunit/CRM/Core/BAO/SettingTest.php +++ b/tests/phpunit/CRM/Core/BAO/SettingTest.php @@ -202,5 +202,74 @@ class CRM_Core_BAO_SettingTest extends CiviUnitTestCase { } */ + /** + * Ensure that on_change callbacks fire. + * + * Note: api_v3_SettingTest::testOnChange and CRM_Core_BAO_SettingTest::testOnChange + * are very similar, but they exercise different codepaths. The first uses the API + * and setItems [plural]; the second uses setItem [singular]. + */ + function testOnChange() { + global $_testOnChange_hookCalls; + $this->setMockSettingsMetaData(array( + 'onChangeExample' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'onChangeExample', + 'type' => 'Array', + 'quick_form_type' => 'Element', + 'html_type' => 'advmultiselect', + 'default' => array('CiviEvent', 'CiviContribute'), + 'add' => '4.4', + 'title' => 'List of Components', + 'is_domain' => '1', + 'is_contact' => 0, + 'description' => NULL, + 'help_text' => NULL, + 'on_change' => array( // list of callbacks + array(__CLASS__, '_testOnChange_onChangeExample') + ), + ), + )); + + // set initial value + $_testOnChange_hookCalls = array('count' => 0); + CRM_Core_BAO_Setting::setItem( + array('First', 'Value'), + 'CiviCRM Preferences', + 'onChangeExample' + ); + $this->assertEquals(1, $_testOnChange_hookCalls['count']); + $this->assertEquals(array('First', 'Value'), $_testOnChange_hookCalls['newValue']); + $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']); + + // change value + $_testOnChange_hookCalls = array('count' => 0); + CRM_Core_BAO_Setting::setItem( + array('Second', 'Value'), + 'CiviCRM Preferences', + 'onChangeExample' + ); + $this->assertEquals(1, $_testOnChange_hookCalls['count']); + $this->assertEquals(array('First', 'Value'), $_testOnChange_hookCalls['oldValue']); + $this->assertEquals(array('Second', 'Value'), $_testOnChange_hookCalls['newValue']); + $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']); + } + + /** + * Mock callback for a setting's on_change handler + * + * @param $oldValue + * @param $newValue + * @param $metadata + */ + static function _testOnChange_onChangeExample($oldValue, $newValue, $metadata) { + global $_testOnChange_hookCalls; + $_testOnChange_hookCalls['count']++; + $_testOnChange_hookCalls['oldValue'] = $oldValue; + $_testOnChange_hookCalls['newValue'] = $newValue; + $_testOnChange_hookCalls['metadata'] = $metadata; + } + } diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index c318b003a3..bbd4d12ae2 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -2267,6 +2267,30 @@ AND ( TABLE_NAME LIKE 'civicrm_value_%' ) } } + /** + * Temporarily alter the settings-metadata to add a mock setting. + * + * WARNING: The setting metadata will disappear on the next cache-clear. + * + * @param $extras + * @return void + */ + function setMockSettingsMetaData($extras) { + CRM_Core_BAO_Setting::$_cache = array(); + $this->callAPISuccess('system','flush', array()); + CRM_Core_BAO_Setting::$_cache = array(); + + CRM_Utils_Hook::singleton()->setHook('civicrm_alterSettingsMetaData', function (&$metadata, $domainId, $profile) use ($extras) { + $metadata = array_merge($metadata, $extras); + }); + + $fields = $this->callAPISuccess('setting', 'getfields', array()); + foreach ($extras as $key => $spec) { + $this->assertNotEmpty($spec['title']); + $this->assertEquals($spec['title'], $fields['values'][$key]['title']); + } + } + function financialAccountDelete($name) { $financialAccount = new CRM_Financial_DAO_FinancialAccount(); $financialAccount->name = $name; diff --git a/tests/phpunit/api/v3/SettingTest.php b/tests/phpunit/api/v3/SettingTest.php index 505b0557a2..6f67edc218 100644 --- a/tests/phpunit/api/v3/SettingTest.php +++ b/tests/phpunit/api/v3/SettingTest.php @@ -124,6 +124,72 @@ class api_v3_SettingTest extends CiviUnitTestCase { $this->assertArrayNotHasKey('customCSSURL', $result['values']); $this->assertArrayHasKey('advanced_search_options',$result['values']); } + + /** + * Ensure that on_change callbacks fire. + * + * Note: api_v3_SettingTest::testOnChange and CRM_Core_BAO_SettingTest::testOnChange + * are very similar, but they exercise different codepaths. The first uses the API + * and setItems [plural]; the second uses setItem [singular]. + */ + function testOnChange() { + global $_testOnChange_hookCalls; + $this->setMockSettingsMetaData(array( + 'onChangeExample' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'onChangeExample', + 'type' => 'Array', + 'quick_form_type' => 'Element', + 'html_type' => 'advmultiselect', + 'default' => array('CiviEvent', 'CiviContribute'), + 'add' => '4.4', + 'title' => 'List of Components', + 'is_domain' => '1', + 'is_contact' => 0, + 'description' => NULL, + 'help_text' => NULL, + 'on_change' => array( // list of callbacks + array(__CLASS__, '_testOnChange_onChangeExample') + ), + ), + )); + + // set initial value + $_testOnChange_hookCalls = array('count' => 0); + $this->callAPISuccess('setting', 'create', array( + 'onChangeExample' => array('First', 'Value'), + )); + $this->assertEquals(1, $_testOnChange_hookCalls['count']); + $this->assertEquals(array('First', 'Value'), $_testOnChange_hookCalls['newValue']); + $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']); + + // change value + $_testOnChange_hookCalls = array('count' => 0); + $this->callAPISuccess('setting', 'create', array( + 'onChangeExample' => array('Second', 'Value'), + )); + $this->assertEquals(1, $_testOnChange_hookCalls['count']); + $this->assertEquals(array('First', 'Value'), $_testOnChange_hookCalls['oldValue']); + $this->assertEquals(array('Second', 'Value'), $_testOnChange_hookCalls['newValue']); + $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']); + } + + /** + * Mock callback for a setting's on_change handler + * + * @param $oldValue + * @param $newValue + * @param $metadata + */ + static function _testOnChange_onChangeExample($oldValue, $newValue, $metadata) { + global $_testOnChange_hookCalls; + $_testOnChange_hookCalls['count']++; + $_testOnChange_hookCalls['oldValue'] = $oldValue; + $_testOnChange_hookCalls['newValue'] = $newValue; + $_testOnChange_hookCalls['metadata'] = $metadata; + } + /** * check getfields works */ -- 2.25.1