3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
13 * Test APIv3 civicrm_setting_* functions
15 * @package CiviCRM_APIv3
16 * @subpackage API_Core
20 * Class contains api test cases for civicrm settings
24 class api_v3_SettingTest
extends CiviUnitTestCase
{
26 protected $_contactID;
28 protected $_currentDomain;
29 protected $_domainID2;
30 protected $_domainID3;
32 public function setUp() {
35 'name' => __CLASS__
. 'Second Domain',
36 'domain_version' => CRM_Utils_System
::version(),
38 $result = $this->callAPISuccess('domain', 'get', $params);
39 if (empty($result['id'])) {
40 $result = $this->callAPISuccess('domain', 'create', $params);
42 $this->_domainID2
= $result['id'];
43 $params['name'] = __CLASS__
. 'Third domain';
44 $result = $this->callAPISuccess('domain', 'get', $params);
45 if (empty($result['id'])) {
46 $result = $this->callAPISuccess('domain', 'create', $params);
48 $this->_domainID3
= $result['id'];
49 $this->_currentDomain
= CRM_Core_Config
::domainID();
50 $this->hookClass
= CRM_Utils_Hook
::singleton();
53 public function tearDown() {
54 CRM_Utils_Hook
::singleton()->reset();
56 $this->callAPISuccess('system', 'flush', []);
57 CRM_Core_DAO
::executeQuery('DELETE FROM civicrm_domain WHERE name LIKE "' . __CLASS__
. '%"');
61 * Set additional settings into metadata (implements hook)
62 * @param array $metaDataFolders
64 public function setExtensionMetadata(&$metaDataFolders) {
66 $metaDataFolders[] = $civicrm_root . '/tests/phpunit/api/v3/settings';
71 * @dataProvider versionThreeAndFour
73 public function testGetFields($version) {
74 $this->_apiversion
= $version;
75 $description = 'Demonstrate return from getfields - see subfolder for variants';
76 $result = $this->callAPIAndDocument('setting', 'getfields', [], __FUNCTION__
, __FILE__
, $description);
77 $this->assertArrayHasKey('customCSSURL', $result['values']);
79 $description = 'Demonstrate return from getfields';
80 $result = $this->callAPISuccess('setting', 'getfields', []);
81 $this->assertArrayHasKey('customCSSURL', $result['values']);
82 $this->callAPISuccess('system', 'flush', []);
86 * Let's check it's loading from cache by meddling with the cache
88 * @dataProvider versionThreeAndFour
90 public function testGetFieldsCaching($version) {
91 $this->_apiversion
= $version;
92 $settingsMetadata = [];
93 Civi
::cache('settings')->set('settingsMetadata_' . \CRM_Core_Config
::domainID() . '_', $settingsMetadata);
94 $result = $this->callAPISuccess('setting', 'getfields', []);
95 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
96 $this->quickCleanup(['civicrm_cache']);
97 Civi
::cache('settings')->flush();
101 * @param int $version
102 * @dataProvider versionThreeAndFour
104 public function testGetFieldsFilters($version) {
105 $this->_apiversion
= $version;
106 $params = ['name' => 'advanced_search_options'];
107 $result = $this->callAPISuccess('setting', 'getfields', $params);
108 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
109 $this->assertArrayHasKey('advanced_search_options', $result['values']);
113 * Test that getfields will filter on group.
114 * @param int $version
115 * @dataProvider versionThreeAndFour
117 public function testGetFieldsGroupFilters($version) {
118 $this->_apiversion
= $version;
119 $params = ['filters' => ['group' => 'multisite']];
120 $result = $this->callAPISuccess('setting', 'getfields', $params);
121 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
122 $this->assertArrayHasKey('domain_group_id', $result['values']);
126 * Ensure that on_change callbacks fire.
128 * Note: api_v3_SettingTest::testOnChange and CRM_Core_BAO_SettingTest::testOnChange
129 * are very similar, but they exercise different codepaths. The first uses the API
130 * and setItems [plural]; the second uses setItem [singular].
131 * @param int $version
132 * @dataProvider versionThreeAndFour
134 public function testOnChange($version) {
135 $this->_apiversion
= $version;
136 global $_testOnChange_hookCalls;
137 $this->setMockSettingsMetaData([
138 'onChangeExample' => [
139 'group_name' => 'CiviCRM Preferences',
141 'name' => 'onChangeExample',
143 'quick_form_type' => 'Element',
144 'html_type' => 'advmultiselect',
145 'default' => ['CiviEvent', 'CiviContribute'],
147 'title' => 'List of Components',
150 'description' => NULL,
154 [__CLASS__
, '_testOnChange_onChangeExample'],
160 $_testOnChange_hookCalls = ['count' => 0];
161 $this->callAPISuccess('setting', 'create', [
162 'onChangeExample' => ['First', 'Value'],
164 $this->assertEquals(1, $_testOnChange_hookCalls['count']);
165 $this->assertEquals(['First', 'Value'], $_testOnChange_hookCalls['newValue']);
166 $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']);
169 $_testOnChange_hookCalls = ['count' => 0];
170 $this->callAPISuccess('setting', 'create', [
171 'onChangeExample' => ['Second', 'Value'],
173 $this->assertEquals(1, $_testOnChange_hookCalls['count']);
174 $this->assertEquals(['First', 'Value'], $_testOnChange_hookCalls['oldValue']);
175 $this->assertEquals(['Second', 'Value'], $_testOnChange_hookCalls['newValue']);
176 $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']);
180 * Mock callback for a setting's on_change handler
186 public static function _testOnChange_onChangeExample($oldValue, $newValue, $metadata) {
187 global $_testOnChange_hookCalls;
188 $_testOnChange_hookCalls['count']++
;
189 $_testOnChange_hookCalls['oldValue'] = $oldValue;
190 $_testOnChange_hookCalls['newValue'] = $newValue;
191 $_testOnChange_hookCalls['metadata'] = $metadata;
195 * @param int $version
196 * @dataProvider versionThreeAndFour
198 public function testCreateSetting($version) {
199 $this->_apiversion
= $version;
200 $description = "Shows setting a variable for a given domain - if no domain is set current is assumed.";
203 'domain_id' => $this->_domainID2
,
204 'uniq_email_per_site' => 1,
206 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
);
208 $params = ['uniq_email_per_site' => 1];
209 $description = "Shows setting a variable for a current domain.";
210 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
, $description, 'CreateSettingCurrentDomain');
211 $this->assertArrayHasKey(CRM_Core_Config
::domainID(), $result['values']);
215 * @param int $version
216 * @dataProvider versionThreeAndFour
218 public function testCreateInvalidSettings($version) {
219 $this->_apiversion
= $version;
221 'domain_id' => $this->_domainID2
,
224 $result = $this->callAPIFailure('setting', 'create', $params);
228 * Check invalid settings rejected -
229 * @param int $version
230 * @dataProvider versionThreeAndFour
232 public function testCreateInvalidURLSettings($version) {
233 $this->_apiversion
= $version;
235 'domain_id' => $this->_domainID2
,
236 'userFrameworkResourceURL' => 'dfhkd hfd',
238 $result = $this->callAPIFailure('setting', 'create', $params);
240 'domain_id' => $this->_domainID2
,
241 'userFrameworkResourceURL' => 'http://blah.com',
243 $result = $this->callAPISuccess('setting', 'create', $params);
247 * @param int $version
248 * @dataProvider versionThreeAndFour
250 public function testCreateInvalidBooleanSettings($version) {
251 $this->_apiversion
= $version;
253 'domain_id' => $this->_domainID2
,
254 'track_civimail_replies' => 'dfhkdhfd',
256 $result = $this->callAPIFailure('setting', 'create', $params);
258 $params = ['track_civimail_replies' => '0'];
259 $result = $this->callAPISuccess('setting', 'create', $params);
260 $getResult = $this->callAPISuccess('setting', 'get');
261 $this->assertEquals(0, $getResult['values'][$this->_currentDomain
]['track_civimail_replies']);
263 $getResult = $this->callAPISuccess('setting', 'get');
264 $this->assertEquals(0, $getResult['values'][$this->_currentDomain
]['track_civimail_replies']);
266 'domain_id' => $this->_domainID2
,
267 'track_civimail_replies' => '1',
269 $result = $this->callAPISuccess('setting', 'create', $params);
270 $getResult = $this->callAPISuccess('setting', 'get', ['domain_id' => $this->_domainID2
]);
271 $this->assertEquals(1, $getResult['values'][$this->_domainID2
]['track_civimail_replies']);
274 'domain_id' => $this->_domainID2
,
275 'track_civimail_replies' => 'TRUE',
277 $result = $this->callAPISuccess('setting', 'create', $params);
278 $getResult = $this->callAPISuccess('setting', 'get', ['domain_id' => $this->_domainID2
]);
280 $this->assertEquals(1, $getResult['values'][$this->_domainID2
]['track_civimail_replies'], "check TRUE is converted to 1");
284 * @param int $version
285 * @dataProvider versionThreeAndFour
287 public function testCreateSettingMultipleDomains($version) {
288 $this->_apiversion
= $version;
289 $description = "Shows setting a variable for all domains.";
292 'domain_id' => 'all',
293 'uniq_email_per_site' => 1,
295 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
, $description, 'CreateAllDomains');
297 $this->assertEquals(1, $result['values'][$this->_domainID2
]['uniq_email_per_site']);
298 $this->assertEquals(1, $result['values'][$this->_currentDomain
]['uniq_email_per_site']);
299 $this->assertArrayHasKey($this->_domainID3
, $result['values'], 'Domain create probably failed Debug this IF domain test is passing');
300 $this->assertEquals(1, $result['values'][$this->_domainID3
]['uniq_email_per_site'], 'failed to set setting for domain 3.');
303 'domain_id' => 'all',
304 'return' => 'uniq_email_per_site',
306 // we'll check it with a 'get'
307 $description = "Shows getting a variable for all domains.";
308 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
, $description, 'GetAllDomains');
310 $this->assertEquals(1, $result['values'][$this->_domainID2
]['uniq_email_per_site']);
311 $this->assertEquals(1, $result['values'][$this->_currentDomain
]['uniq_email_per_site']);
312 $this->assertEquals(1, $result['values'][$this->_domainID3
]['uniq_email_per_site']);
315 'domain_id' => [$this->_currentDomain
, $this->_domainID3
],
316 'uniq_email_per_site' => 0,
318 $description = "Shows setting a variable for specified domains.";
319 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
, $description, 'CreateSpecifiedDomains');
321 $this->assertEquals(0, $result['values'][$this->_domainID3
]['uniq_email_per_site']);
322 $this->assertEquals(0, $result['values'][$this->_currentDomain
]['uniq_email_per_site']);
324 'domain_id' => [$this->_currentDomain
, $this->_domainID2
],
325 'return' => ['uniq_email_per_site'],
327 $description = "Shows getting a variable for specified domains.";
328 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
, $description, 'GetSpecifiedDomains');
329 $this->assertEquals(1, $result['values'][$this->_domainID2
]['uniq_email_per_site']);
330 $this->assertEquals(0, $result['values'][$this->_currentDomain
]['uniq_email_per_site']);
335 * @param int $version
336 * @dataProvider versionThreeAndFour
338 public function testGetSetting($version) {
339 $this->_apiversion
= $version;
341 'domain_id' => $this->_domainID2
,
342 'return' => 'uniq_email_per_site',
344 $description = "Shows get setting a variable for a given domain - if no domain is set current is assumed.";
346 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
);
349 'return' => 'uniq_email_per_site',
351 $description = "Shows getting a variable for a current domain.";
352 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
, $description, 'GetSettingCurrentDomain');
353 $this->assertArrayHasKey(CRM_Core_Config
::domainID(), $result['values']);
357 * Check that setting defined in extension can be retrieved.
358 * @param int $version
359 * @dataProvider versionThreeAndFour
361 public function testGetExtensionSetting($version) {
362 $this->_apiversion
= $version;
363 $this->hookClass
->setHook('civicrm_alterSettingsFolders', [$this, 'setExtensionMetadata']);
365 Civi
::cache('settings')->flush();
366 $fields = $this->callAPISuccess('setting', 'getfields', ['filters' => ['group_name' => 'Test Settings']]);
367 $this->assertArrayHasKey('test_key', $fields['values']);
368 $this->callAPISuccess('setting', 'create', ['test_key' => 'keyset']);
369 $this->assertEquals('keyset', Civi
::settings()->get('test_key'));
370 $result = $this->callAPISuccess('setting', 'getvalue', ['name' => 'test_key', 'group' => 'Test Settings']);
371 $this->assertEquals('keyset', $result);
375 * Setting api should set & fetch settings stored in config as well as those in settings table
376 * @param int $version
377 * @dataProvider versionThreeAndFour
379 public function testGetConfigSetting($version) {
380 $this->_apiversion
= $version;
381 $settings = $this->callAPISuccess('setting', 'get', [
382 'name' => 'defaultCurrency',
385 $this->assertEquals('USD', $settings['values'][0]['defaultCurrency']);
389 * Setting api should set & fetch settings stored in config as well as those in settings table
390 * @param int $version
391 * @dataProvider versionThreeAndFour
393 public function testGetSetConfigSettingMultipleDomains($version) {
394 $this->_apiversion
= $version;
395 $settings = $this->callAPISuccess('setting', 'create', [
396 'defaultCurrency' => 'USD',
397 'domain_id' => $this->_currentDomain
,
399 $settings = $this->callAPISuccess('setting', 'create', [
400 'defaultCurrency' => 'CAD',
401 'domain_id' => $this->_domainID2
,
403 $settings = $this->callAPISuccess('setting', 'get', [
404 'return' => 'defaultCurrency',
405 'domain_id' => 'all',
407 $this->assertEquals('USD', $settings['values'][$this->_currentDomain
]['defaultCurrency']);
408 $this->assertEquals('CAD', $settings['values'][$this->_domainID2
]['defaultCurrency'],
409 "second domain (id {$this->_domainID2} ) should be set to CAD. First dom was {$this->_currentDomain} & was USD");
414 * Use getValue against a config setting.
415 * @param int $version
416 * @dataProvider versionThreeAndFour
418 public function testGetValueConfigSetting($version) {
419 $this->_apiversion
= $version;
421 'name' => 'monetaryThousandSeparator',
422 'group' => 'Localization Setting',
424 $result = $this->callAPISuccess('setting', 'getvalue', $params);
425 $this->assertEquals(',', $result);
429 * @param int $version
430 * @dataProvider versionThreeAndFour
432 public function testGetValue($version) {
433 $this->_apiversion
= $version;
435 'name' => 'petition_contacts',
436 'group' => 'Campaign Preferences',
438 $description = "Demonstrates getvalue action - intended for runtime use as better caching than get.";
440 $result = $this->callAPIAndDocument('setting', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description);
441 $this->assertEquals('Petition Contacts', $result);
445 * V3 only - no api4 equivalent.
447 public function testGetDefaults() {
448 $description = "Gets defaults setting a variable for a given domain - if no domain is set current is assumed.";
451 'name' => 'address_format',
453 $result = $this->callAPIAndDocument('setting', 'getdefaults', $params, __FUNCTION__
, __FILE__
, $description, 'GetDefaults');
454 $this->assertEquals("{contact.address_name}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.supplemental_address_3}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config
::domainID()]['address_format']);
455 $params = ['name' => 'mailing_format'];
456 $result = $this->callAPISuccess('setting', 'getdefaults', $params);
457 $this->assertEquals("{contact.addressee}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.supplemental_address_3}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config
::domainID()]['mailing_format']);
458 $this->assertArrayHasKey(CRM_Core_Config
::domainID(), $result['values']);
462 * Function tests reverting a specific parameter.
463 * @param int $version
464 * @dataProvider versionThreeAndFour
466 public function testRevert($version) {
467 $this->_apiversion
= $version;
469 'address_format' => 'xyz',
470 'mailing_format' => 'bcs',
472 $result = $this->callAPISuccess('setting', 'create', $params);
473 $this->assertAPISuccess($result, "in line " . __LINE__
);
475 'name' => 'address_format',
477 $result = $this->callAPISuccess('setting', 'get');
479 $this->assertEquals('xyz', $result['values'][CRM_Core_Config
::domainID()]['address_format']);
480 $description = "Demonstrates reverting a parameter to default value.";
481 $result = $this->callAPIAndDocument('setting', 'revert', $revertParams, __FUNCTION__
, __FILE__
, $description, '');
482 //make sure it's reverted
483 $result = $this->callAPISuccess('setting', 'get');
484 $this->assertEquals("{contact.address_name}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.supplemental_address_3}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config
::domainID()]['address_format']);
486 'return' => ['mailing_format'],
488 $result = $this->callAPISuccess('setting', 'get', $params);
489 //make sure it's unchanged
490 $this->assertEquals('bcs', $result['values'][CRM_Core_Config
::domainID()]['mailing_format']);
494 * Tests reverting ALL parameters (specific domain)
497 public function testRevertAll() {
499 'address_format' => 'xyz',
500 'mailing_format' => 'bcs',
502 $result = $this->callAPISuccess('setting', 'create', $params);
504 $result = $this->callAPISuccess('setting', 'get', $params);
506 $this->assertEquals('xyz', $result['values'][CRM_Core_Config
::domainID()]['address_format']);
508 $this->callAPISuccess('setting', 'revert', $revertParams);
509 //make sure it's reverted
510 $result = $this->callAPISuccess('setting', 'get', ['group' => 'core']);
511 $this->assertEquals("{contact.address_name}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.supplemental_address_3}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config
::domainID()]['address_format']);
512 $this->assertEquals("{contact.addressee}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.supplemental_address_3}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config
::domainID()]['mailing_format']);
516 * Settings should respect their defaults
517 * V3 only - no fill action in v4
519 public function testDefaults() {
521 'name' => __CLASS__
. 'B Team Domain',
522 'domain_version' => CRM_Utils_System
::version(),
524 $dom = $this->callAPISuccess('domain', 'create', $domparams);
526 'domain_id' => 'all',
528 $result = $this->callAPISuccess('setting', 'get', $params);
530 'address_format' => 'xyz',
531 'mailing_format' => 'bcs',
532 'domain_id' => $this->_domainID2
,
534 $result = $this->callAPISuccess('setting', 'create', $params);
536 'domain_id' => $dom['id'],
538 $result = $this->callAPISuccess('setting', 'get', $params);
539 $this->assertAPISuccess($result, "in line " . __LINE__
);
540 $this->assertEquals('Unconfirmed', $result['values'][$dom['id']]['tag_unconfirmed']);
542 // The 'fill' operation is no longer necessary, but third parties might still use it, so let's
543 // make sure it doesn't do anything weird (crashing or breaking values).
544 $result = $this->callAPISuccess('setting', 'fill', $params);
545 $this->assertAPISuccess($result, "in line " . __LINE__
);
546 $result = $this->callAPISuccess('setting', 'get', $params);
547 $this->assertAPISuccess($result, "in line " . __LINE__
);
548 $this->assertArrayHasKey('tag_unconfirmed', $result['values'][$dom['id']]);
550 // Setting has NULL default. Not returned.
551 //$this->assertArrayHasKey('extensionsDir', $result['values'][$dom['id']]);
553 $this->assertEquals('Unconfirmed', $result['values'][$dom['id']]['tag_unconfirmed']);
557 * Test to set isProductionEnvironment
558 * @param int $version
559 * @dataProvider versionThreeAndFour
561 public function testSetCivicrmEnvironment($version) {
562 $this->_apiversion
= $version;
563 global $civicrm_setting;
564 unset($civicrm_setting[CRM_Core_BAO_Setting
::DEVELOPER_PREFERENCES_NAME
]['environment']);
565 Civi
::service('settings_manager')->useMandatory();
567 'environment' => 'Staging',
569 $result = $this->callAPISuccess('Setting', 'create', $params);
571 'name' => 'environment',
572 'group' => 'Developer Preferences',
574 $result = $this->callAPISuccess('Setting', 'getvalue', $params);
575 $this->assertEquals('Staging', $result);
577 $civicrm_setting[CRM_Core_BAO_Setting
::DEVELOPER_PREFERENCES_NAME
]['environment'] = 'Production';
578 Civi
::service('settings_manager')->useMandatory();
579 $result = $this->callAPISuccess('Setting', 'getvalue', $params);
580 $this->assertEquals('Production', $result);