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' => 'Default Domain Name',
36 'domain_version' => '4.7',
38 $result = $this->callAPISuccess('domain', 'get', $params);
39 if (empty($result['id'])) {
40 $result = $this->callAPISuccess('domain', 'create', $params);
43 $params['name'] = 'Second Domain';
44 $result = $this->callAPISuccess('domain', 'get', $params);
45 if (empty($result['id'])) {
46 $result = $this->callAPISuccess('domain', 'create', $params);
48 $this->_domainID2
= $result['id'];
49 $params['name'] = 'A-team domain';
50 $result = $this->callAPISuccess('domain', 'get', $params);
51 if (empty($result['id'])) {
52 $result = $this->callAPISuccess('domain', 'create', $params);
54 $this->_domainID3
= $result['id'];
55 $this->_currentDomain
= CRM_Core_Config
::domainID();
56 $this->hookClass
= CRM_Utils_Hook
::singleton();
59 public function tearDown() {
60 CRM_Utils_Hook
::singleton()->reset();
62 $this->callAPISuccess('system', 'flush', []);
63 $this->quickCleanup(['civicrm_domain']);
67 * Set additional settings into metadata (implements hook)
68 * @param array $metaDataFolders
70 public function setExtensionMetadata(&$metaDataFolders) {
72 $metaDataFolders[] = $civicrm_root . '/tests/phpunit/api/v3/settings';
77 * @dataProvider versionThreeAndFour
79 public function testGetFields($version) {
80 $this->_apiversion
= $version;
81 $description = 'Demonstrate return from getfields - see subfolder for variants';
82 $result = $this->callAPIAndDocument('setting', 'getfields', [], __FUNCTION__
, __FILE__
, $description);
83 $this->assertArrayHasKey('customCSSURL', $result['values']);
85 $description = 'Demonstrate return from getfields';
86 $result = $this->callAPISuccess('setting', 'getfields', []);
87 $this->assertArrayHasKey('customCSSURL', $result['values']);
88 $this->callAPISuccess('system', 'flush', []);
92 * Let's check it's loading from cache by meddling with the cache
94 * @dataProvider versionThreeAndFour
96 public function testGetFieldsCaching($version) {
97 $this->_apiversion
= $version;
98 $settingsMetadata = [];
99 Civi
::cache('settings')->set('settingsMetadata_' . \CRM_Core_Config
::domainID() . '_', $settingsMetadata);
100 $result = $this->callAPISuccess('setting', 'getfields', []);
101 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
102 $this->quickCleanup(['civicrm_cache']);
103 Civi
::cache('settings')->flush();
107 * @param int $version
108 * @dataProvider versionThreeAndFour
110 public function testGetFieldsFilters($version) {
111 $this->_apiversion
= $version;
112 $params = ['name' => 'advanced_search_options'];
113 $result = $this->callAPISuccess('setting', 'getfields', $params);
114 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
115 $this->assertArrayHasKey('advanced_search_options', $result['values']);
119 * Test that getfields will filter on group.
120 * @param int $version
121 * @dataProvider versionThreeAndFour
123 public function testGetFieldsGroupFilters($version) {
124 $this->_apiversion
= $version;
125 $params = ['filters' => ['group' => 'multisite']];
126 $result = $this->callAPISuccess('setting', 'getfields', $params);
127 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
128 $this->assertArrayHasKey('domain_group_id', $result['values']);
132 * Ensure that on_change callbacks fire.
134 * Note: api_v3_SettingTest::testOnChange and CRM_Core_BAO_SettingTest::testOnChange
135 * are very similar, but they exercise different codepaths. The first uses the API
136 * and setItems [plural]; the second uses setItem [singular].
137 * @param int $version
138 * @dataProvider versionThreeAndFour
140 public function testOnChange($version) {
141 $this->_apiversion
= $version;
142 global $_testOnChange_hookCalls;
143 $this->setMockSettingsMetaData([
144 'onChangeExample' => [
145 'group_name' => 'CiviCRM Preferences',
147 'name' => 'onChangeExample',
149 'quick_form_type' => 'Element',
150 'html_type' => 'advmultiselect',
151 'default' => ['CiviEvent', 'CiviContribute'],
153 'title' => 'List of Components',
156 'description' => NULL,
160 [__CLASS__
, '_testOnChange_onChangeExample'],
166 $_testOnChange_hookCalls = ['count' => 0];
167 $this->callAPISuccess('setting', 'create', [
168 'onChangeExample' => ['First', 'Value'],
170 $this->assertEquals(1, $_testOnChange_hookCalls['count']);
171 $this->assertEquals(['First', 'Value'], $_testOnChange_hookCalls['newValue']);
172 $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']);
175 $_testOnChange_hookCalls = ['count' => 0];
176 $this->callAPISuccess('setting', 'create', [
177 'onChangeExample' => ['Second', 'Value'],
179 $this->assertEquals(1, $_testOnChange_hookCalls['count']);
180 $this->assertEquals(['First', 'Value'], $_testOnChange_hookCalls['oldValue']);
181 $this->assertEquals(['Second', 'Value'], $_testOnChange_hookCalls['newValue']);
182 $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']);
186 * Mock callback for a setting's on_change handler
192 public static function _testOnChange_onChangeExample($oldValue, $newValue, $metadata) {
193 global $_testOnChange_hookCalls;
194 $_testOnChange_hookCalls['count']++
;
195 $_testOnChange_hookCalls['oldValue'] = $oldValue;
196 $_testOnChange_hookCalls['newValue'] = $newValue;
197 $_testOnChange_hookCalls['metadata'] = $metadata;
201 * @param int $version
202 * @dataProvider versionThreeAndFour
204 public function testCreateSetting($version) {
205 $this->_apiversion
= $version;
206 $description = "Shows setting a variable for a given domain - if no domain is set current is assumed.";
209 'domain_id' => $this->_domainID2
,
210 'uniq_email_per_site' => 1,
212 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
);
214 $params = ['uniq_email_per_site' => 1];
215 $description = "Shows setting a variable for a current domain.";
216 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
, $description, 'CreateSettingCurrentDomain');
217 $this->assertArrayHasKey(CRM_Core_Config
::domainID(), $result['values']);
221 * @param int $version
222 * @dataProvider versionThreeAndFour
224 public function testCreateInvalidSettings($version) {
225 $this->_apiversion
= $version;
227 'domain_id' => $this->_domainID2
,
230 $result = $this->callAPIFailure('setting', 'create', $params);
234 * Check invalid settings rejected -
235 * @param int $version
236 * @dataProvider versionThreeAndFour
238 public function testCreateInvalidURLSettings($version) {
239 $this->_apiversion
= $version;
241 'domain_id' => $this->_domainID2
,
242 'userFrameworkResourceURL' => 'dfhkd hfd',
244 $result = $this->callAPIFailure('setting', 'create', $params);
246 'domain_id' => $this->_domainID2
,
247 'userFrameworkResourceURL' => 'http://blah.com',
249 $result = $this->callAPISuccess('setting', 'create', $params);
253 * @param int $version
254 * @dataProvider versionThreeAndFour
256 public function testCreateInvalidBooleanSettings($version) {
257 $this->_apiversion
= $version;
259 'domain_id' => $this->_domainID2
,
260 'track_civimail_replies' => 'dfhkdhfd',
262 $result = $this->callAPIFailure('setting', 'create', $params);
264 $params = ['track_civimail_replies' => '0'];
265 $result = $this->callAPISuccess('setting', 'create', $params);
266 $getResult = $this->callAPISuccess('setting', 'get');
267 $this->assertEquals(0, $getResult['values'][$this->_currentDomain
]['track_civimail_replies']);
269 $getResult = $this->callAPISuccess('setting', 'get');
270 $this->assertEquals(0, $getResult['values'][$this->_currentDomain
]['track_civimail_replies']);
272 'domain_id' => $this->_domainID2
,
273 'track_civimail_replies' => '1',
275 $result = $this->callAPISuccess('setting', 'create', $params);
276 $getResult = $this->callAPISuccess('setting', 'get', ['domain_id' => $this->_domainID2
]);
277 $this->assertEquals(1, $getResult['values'][$this->_domainID2
]['track_civimail_replies']);
280 'domain_id' => $this->_domainID2
,
281 'track_civimail_replies' => 'TRUE',
283 $result = $this->callAPISuccess('setting', 'create', $params);
284 $getResult = $this->callAPISuccess('setting', 'get', ['domain_id' => $this->_domainID2
]);
286 $this->assertEquals(1, $getResult['values'][$this->_domainID2
]['track_civimail_replies'], "check TRUE is converted to 1");
290 * @param int $version
291 * @dataProvider versionThreeAndFour
293 public function testCreateSettingMultipleDomains($version) {
294 $this->_apiversion
= $version;
295 $description = "Shows setting a variable for all domains.";
298 'domain_id' => 'all',
299 'uniq_email_per_site' => 1,
301 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
, $description, 'CreateAllDomains');
303 $this->assertEquals(1, $result['values'][2]['uniq_email_per_site']);
304 $this->assertEquals(1, $result['values'][1]['uniq_email_per_site']);
305 $this->assertArrayHasKey(3, $result['values'], 'Domain create probably failed Debug this IF domain test is passing');
306 $this->assertEquals(1, $result['values'][3]['uniq_email_per_site'], 'failed to set setting for domain 3.');
309 'domain_id' => 'all',
310 'return' => 'uniq_email_per_site',
312 // we'll check it with a 'get'
313 $description = "Shows getting a variable for all domains.";
314 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
, $description, 'GetAllDomains');
316 $this->assertEquals(1, $result['values'][2]['uniq_email_per_site']);
317 $this->assertEquals(1, $result['values'][1]['uniq_email_per_site']);
318 $this->assertEquals(1, $result['values'][3]['uniq_email_per_site']);
321 'domain_id' => [1, 3],
322 'uniq_email_per_site' => 0,
324 $description = "Shows setting a variable for specified domains.";
325 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__
, __FILE__
, $description, 'CreateSpecifiedDomains');
327 $this->assertEquals(0, $result['values'][3]['uniq_email_per_site']);
328 $this->assertEquals(0, $result['values'][1]['uniq_email_per_site']);
330 'domain_id' => [1, 2],
331 'return' => ['uniq_email_per_site'],
333 $description = "Shows getting a variable for specified domains.";
334 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
, $description, 'GetSpecifiedDomains');
335 $this->assertEquals(1, $result['values'][2]['uniq_email_per_site']);
336 $this->assertEquals(0, $result['values'][1]['uniq_email_per_site']);
341 * @param int $version
342 * @dataProvider versionThreeAndFour
344 public function testGetSetting($version) {
345 $this->_apiversion
= $version;
347 'domain_id' => $this->_domainID2
,
348 'return' => 'uniq_email_per_site',
350 $description = "Shows get setting a variable for a given domain - if no domain is set current is assumed.";
352 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
);
355 'return' => 'uniq_email_per_site',
357 $description = "Shows getting a variable for a current domain.";
358 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__
, __FILE__
, $description, 'GetSettingCurrentDomain');
359 $this->assertArrayHasKey(CRM_Core_Config
::domainID(), $result['values']);
363 * Check that setting defined in extension can be retrieved.
364 * @param int $version
365 * @dataProvider versionThreeAndFour
367 public function testGetExtensionSetting($version) {
368 $this->_apiversion
= $version;
369 $this->hookClass
->setHook('civicrm_alterSettingsFolders', [$this, 'setExtensionMetadata']);
371 Civi
::cache('settings')->flush();
372 $fields = $this->callAPISuccess('setting', 'getfields', ['filters' => ['group_name' => 'Test Settings']]);
373 $this->assertArrayHasKey('test_key', $fields['values']);
374 $this->callAPISuccess('setting', 'create', ['test_key' => 'keyset']);
375 $this->assertEquals('keyset', Civi
::settings()->get('test_key'));
376 $result = $this->callAPISuccess('setting', 'getvalue', ['name' => 'test_key', 'group' => 'Test Settings']);
377 $this->assertEquals('keyset', $result);
381 * Setting api should set & fetch settings stored in config as well as those in settings table
382 * @param int $version
383 * @dataProvider versionThreeAndFour
385 public function testGetConfigSetting($version) {
386 $this->_apiversion
= $version;
387 $settings = $this->callAPISuccess('setting', 'get', [
388 'name' => 'defaultCurrency',
391 $this->assertEquals('USD', $settings['values'][0]['defaultCurrency']);
395 * Setting api should set & fetch settings stored in config as well as those in settings table
396 * @param int $version
397 * @dataProvider versionThreeAndFour
399 public function testGetSetConfigSettingMultipleDomains($version) {
400 $this->_apiversion
= $version;
401 $settings = $this->callAPISuccess('setting', 'create', [
402 'defaultCurrency' => 'USD',
403 'domain_id' => $this->_currentDomain
,
405 $settings = $this->callAPISuccess('setting', 'create', [
406 'defaultCurrency' => 'CAD',
407 'domain_id' => $this->_domainID2
,
409 $settings = $this->callAPISuccess('setting', 'get', [
410 'return' => 'defaultCurrency',
411 'domain_id' => 'all',
413 $this->assertEquals('USD', $settings['values'][$this->_currentDomain
]['defaultCurrency']);
414 $this->assertEquals('CAD', $settings['values'][$this->_domainID2
]['defaultCurrency'],
415 "second domain (id {$this->_domainID2} ) should be set to CAD. First dom was {$this->_currentDomain} & was USD");
420 * Use getValue against a config setting.
421 * @param int $version
422 * @dataProvider versionThreeAndFour
424 public function testGetValueConfigSetting($version) {
425 $this->_apiversion
= $version;
427 'name' => 'monetaryThousandSeparator',
428 'group' => 'Localization Setting',
430 $result = $this->callAPISuccess('setting', 'getvalue', $params);
431 $this->assertEquals(',', $result);
435 * @param int $version
436 * @dataProvider versionThreeAndFour
438 public function testGetValue($version) {
439 $this->_apiversion
= $version;
441 'name' => 'petition_contacts',
442 'group' => 'Campaign Preferences',
444 $description = "Demonstrates getvalue action - intended for runtime use as better caching than get.";
446 $result = $this->callAPIAndDocument('setting', 'getvalue', $params, __FUNCTION__
, __FILE__
, $description);
447 $this->assertEquals('Petition Contacts', $result);
451 * V3 only - no api4 equivalent.
453 public function testGetDefaults() {
454 $description = "Gets defaults setting a variable for a given domain - if no domain is set current is assumed.";
457 'name' => 'address_format',
459 $result = $this->callAPIAndDocument('setting', 'getdefaults', $params, __FUNCTION__
, __FILE__
, $description, 'GetDefaults');
460 $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']);
461 $params = ['name' => 'mailing_format'];
462 $result = $this->callAPISuccess('setting', 'getdefaults', $params);
463 $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']);
464 $this->assertArrayHasKey(CRM_Core_Config
::domainID(), $result['values']);
468 * Function tests reverting a specific parameter.
469 * @param int $version
470 * @dataProvider versionThreeAndFour
472 public function testRevert($version) {
473 $this->_apiversion
= $version;
475 'address_format' => 'xyz',
476 'mailing_format' => 'bcs',
478 $result = $this->callAPISuccess('setting', 'create', $params);
479 $this->assertAPISuccess($result, "in line " . __LINE__
);
481 'name' => 'address_format',
483 $result = $this->callAPISuccess('setting', 'get');
485 $this->assertEquals('xyz', $result['values'][CRM_Core_Config
::domainID()]['address_format']);
486 $description = "Demonstrates reverting a parameter to default value.";
487 $result = $this->callAPIAndDocument('setting', 'revert', $revertParams, __FUNCTION__
, __FILE__
, $description, '');
488 //make sure it's reverted
489 $result = $this->callAPISuccess('setting', 'get');
490 $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']);
492 'return' => ['mailing_format'],
494 $result = $this->callAPISuccess('setting', 'get', $params);
495 //make sure it's unchanged
496 $this->assertEquals('bcs', $result['values'][CRM_Core_Config
::domainID()]['mailing_format']);
500 * Tests reverting ALL parameters (specific domain)
503 public function testRevertAll() {
505 'address_format' => 'xyz',
506 'mailing_format' => 'bcs',
508 $result = $this->callAPISuccess('setting', 'create', $params);
510 $result = $this->callAPISuccess('setting', 'get', $params);
512 $this->assertEquals('xyz', $result['values'][CRM_Core_Config
::domainID()]['address_format']);
514 $this->callAPISuccess('setting', 'revert', $revertParams);
515 //make sure it's reverted
516 $result = $this->callAPISuccess('setting', 'get', ['group' => 'core']);
517 $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']);
518 $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']);
522 * Settings should respect their defaults
523 * V3 only - no fill action in v4
525 public function testDefaults() {
527 'name' => 'B Team Domain',
528 'domain_version' => '4.7',
530 $dom = $this->callAPISuccess('domain', 'create', $domparams);
532 'domain_id' => 'all',
534 $result = $this->callAPISuccess('setting', 'get', $params);
536 'address_format' => 'xyz',
537 'mailing_format' => 'bcs',
538 'domain_id' => $this->_domainID2
,
540 $result = $this->callAPISuccess('setting', 'create', $params);
542 'domain_id' => $dom['id'],
544 $result = $this->callAPISuccess('setting', 'get', $params);
545 $this->assertAPISuccess($result, "in line " . __LINE__
);
546 $this->assertEquals('Unconfirmed', $result['values'][$dom['id']]['tag_unconfirmed']);
548 // The 'fill' operation is no longer necessary, but third parties might still use it, so let's
549 // make sure it doesn't do anything weird (crashing or breaking values).
550 $result = $this->callAPISuccess('setting', 'fill', $params);
551 $this->assertAPISuccess($result, "in line " . __LINE__
);
552 $result = $this->callAPISuccess('setting', 'get', $params);
553 $this->assertAPISuccess($result, "in line " . __LINE__
);
554 $this->assertArrayHasKey('tag_unconfirmed', $result['values'][$dom['id']]);
556 // Setting has NULL default. Not returned.
557 //$this->assertArrayHasKey('extensionsDir', $result['values'][$dom['id']]);
559 $this->assertEquals('Unconfirmed', $result['values'][$dom['id']]['tag_unconfirmed']);
563 * Test to set isProductionEnvironment
564 * @param int $version
565 * @dataProvider versionThreeAndFour
567 public function testSetCivicrmEnvironment($version) {
568 $this->_apiversion
= $version;
569 global $civicrm_setting;
570 unset($civicrm_setting[CRM_Core_BAO_Setting
::DEVELOPER_PREFERENCES_NAME
]['environment']);
571 Civi
::service('settings_manager')->useMandatory();
573 'environment' => 'Staging',
575 $result = $this->callAPISuccess('Setting', 'create', $params);
577 'name' => 'environment',
578 'group' => 'Developer Preferences',
580 $result = $this->callAPISuccess('Setting', 'getvalue', $params);
581 $this->assertEquals('Staging', $result);
583 $civicrm_setting[CRM_Core_BAO_Setting
::DEVELOPER_PREFERENCES_NAME
]['environment'] = 'Production';
584 Civi
::service('settings_manager')->useMandatory();
585 $result = $this->callAPISuccess('Setting', 'getvalue', $params);
586 $this->assertEquals('Production', $result);