Merge remote-tracking branch 'upstream/4.6' into 4.6-master-2015-11-09-14-08-33
[civicrm-core.git] / tests / phpunit / api / v3 / SettingTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 require_once 'CiviTest/CiviUnitTestCase.php';
29
30
31 /**
32 * Test APIv3 civicrm_setting_* functions
33 *
34 * @package CiviCRM_APIv3
35 * @subpackage API_Core
36 */
37
38 /**
39 * Class contains api test cases for civicrm settings
40 *
41 */
42 class api_v3_SettingTest extends CiviUnitTestCase {
43
44 protected $_apiversion = 3;
45 protected $_contactID;
46 protected $_params;
47 protected $_currentDomain;
48 protected $_domainID2;
49 protected $_domainID3;
50
51 public function setUp() {
52 parent::setUp();
53 $params = array(
54 'name' => 'Default Domain Name',
55 );
56 $result = $this->callAPISuccess('domain', 'get', $params);
57 if (empty($result['id'])) {
58 $result = $this->callAPISuccess('domain', 'create', $params);
59 }
60
61 $params['name'] = 'Second Domain';
62 $result = $this->callAPISuccess('domain', 'get', $params);
63 if (empty($result['id'])) {
64 $result = $this->callAPISuccess('domain', 'create', $params);
65 }
66 $this->_domainID2 = $result['id'];
67 $params['name'] = 'A-team domain';
68 $result = $this->callAPISuccess('domain', 'get', $params);
69 if (empty($result['id'])) {
70 $result = $this->callAPISuccess('domain', 'create', $params);
71 }
72 $this->_domainID3 = $result['id'];
73 $this->_currentDomain = CRM_Core_Config::domainID();
74 $this->hookClass = CRM_Utils_Hook::singleton();
75 }
76
77 public function tearDown() {
78 CRM_Utils_Hook::singleton()->reset();
79 parent::tearDown();
80 $this->callAPISuccess('system', 'flush', array());
81 $this->quickCleanup(array('civicrm_domain'));
82 }
83
84 /**
85 * Set additional settings into metadata (implements hook)
86 * @param array $metaDataFolders
87 */
88 public function setExtensionMetadata(&$metaDataFolders) {
89 global $civicrm_root;
90 $metaDataFolders[] = $civicrm_root . '/tests/phpunit/api/v3/settings';
91 }
92
93 /**
94 * /**
95 * Check getfields works.
96 */
97 public function testGetFields() {
98 $description = 'Demonstrate return from getfields - see subfolder for variants';
99 $result = $this->callAPIAndDocument('setting', 'getfields', array(), __FUNCTION__, __FILE__, $description);
100 $this->assertArrayHasKey('customCSSURL', $result['values']);
101
102 $description = 'Demonstrate return from getfields';
103 $result = $this->callAPISuccess('setting', 'getfields', array());
104 $this->assertArrayHasKey('customCSSURL', $result['values']);
105 $this->callAPISuccess('system', 'flush', array());
106 }
107
108 /**
109 * Let's check it's loading from cache by meddling with the cache
110 */
111 public function testGetFieldsCaching() {
112 $settingsMetadata = array();
113 Civi::cache('settings')->set('settingsMetadata_' . \CRM_Core_Config::domainID() . '_', $settingsMetadata);
114 Civi::cache('settings')->set(\Civi\Core\SettingsMetadata::ALL, $settingsMetadata);
115 $result = $this->callAPISuccess('setting', 'getfields', array());
116 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
117 $this->quickCleanup(array('civicrm_cache'));
118 Civi::cache('settings')->flush();
119 }
120
121 public function testGetFieldsFilters() {
122 $params = array('name' => 'advanced_search_options');
123 $result = $this->callAPISuccess('setting', 'getfields', $params);
124 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
125 $this->assertArrayHasKey('advanced_search_options', $result['values']);
126 }
127
128 /**
129 * Test that getfields will filter on group.
130 */
131 public function testGetFieldsGroupFilters() {
132 $params = array('filters' => array('group' => 'multisite'));
133 $result = $this->callAPISuccess('setting', 'getfields', $params);
134 $this->assertArrayNotHasKey('customCSSURL', $result['values']);
135 $this->assertArrayHasKey('domain_group_id', $result['values']);
136 }
137
138 /**
139 * Ensure that on_change callbacks fire.
140 *
141 * Note: api_v3_SettingTest::testOnChange and CRM_Core_BAO_SettingTest::testOnChange
142 * are very similar, but they exercise different codepaths. The first uses the API
143 * and setItems [plural]; the second uses setItem [singular].
144 */
145 public function testOnChange() {
146 global $_testOnChange_hookCalls;
147 $this->setMockSettingsMetaData(array(
148 'onChangeExample' => array(
149 'group_name' => 'CiviCRM Preferences',
150 'group' => 'core',
151 'name' => 'onChangeExample',
152 'type' => 'Array',
153 'quick_form_type' => 'Element',
154 'html_type' => 'advmultiselect',
155 'default' => array('CiviEvent', 'CiviContribute'),
156 'add' => '4.4',
157 'title' => 'List of Components',
158 'is_domain' => '1',
159 'is_contact' => 0,
160 'description' => NULL,
161 'help_text' => NULL,
162 'on_change' => array(// list of callbacks
163 array(__CLASS__, '_testOnChange_onChangeExample'),
164 ),
165 ),
166 ));
167
168 // set initial value
169 $_testOnChange_hookCalls = array('count' => 0);
170 $this->callAPISuccess('setting', 'create', array(
171 'onChangeExample' => array('First', 'Value'),
172 ));
173 $this->assertEquals(1, $_testOnChange_hookCalls['count']);
174 $this->assertEquals(array('First', 'Value'), $_testOnChange_hookCalls['newValue']);
175 $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']);
176
177 // change value
178 $_testOnChange_hookCalls = array('count' => 0);
179 $this->callAPISuccess('setting', 'create', array(
180 'onChangeExample' => array('Second', 'Value'),
181 ));
182 $this->assertEquals(1, $_testOnChange_hookCalls['count']);
183 $this->assertEquals(array('First', 'Value'), $_testOnChange_hookCalls['oldValue']);
184 $this->assertEquals(array('Second', 'Value'), $_testOnChange_hookCalls['newValue']);
185 $this->assertEquals('List of Components', $_testOnChange_hookCalls['metadata']['title']);
186 }
187
188 /**
189 * Mock callback for a setting's on_change handler
190 *
191 * @param $oldValue
192 * @param $newValue
193 * @param $metadata
194 */
195 public static function _testOnChange_onChangeExample($oldValue, $newValue, $metadata) {
196 global $_testOnChange_hookCalls;
197 $_testOnChange_hookCalls['count']++;
198 $_testOnChange_hookCalls['oldValue'] = $oldValue;
199 $_testOnChange_hookCalls['newValue'] = $newValue;
200 $_testOnChange_hookCalls['metadata'] = $metadata;
201 }
202
203 /**
204 * Check getfields works.
205 */
206 public function testCreateSetting() {
207 $description = "Shows setting a variable for a given domain - if no domain is set current is assumed.";
208
209 $params = array(
210 'domain_id' => $this->_domainID2,
211 'uniq_email_per_site' => 1,
212 );
213 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__, __FILE__);
214
215 $params = array('uniq_email_per_site' => 1);
216 $description = "Shows setting a variable for a current domain.";
217 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__, __FILE__, $description, 'CreateSettingCurrentDomain');
218 $this->assertArrayHasKey(CRM_Core_Config::domainID(), $result['values']);
219 }
220
221 /**
222 * Check getfields works.
223 */
224 public function testCreateInvalidSettings() {
225 $params = array(
226 'domain_id' => $this->_domainID2,
227 'invalid_key' => 1,
228 );
229 $result = $this->callAPIFailure('setting', 'create', $params);
230 }
231
232 /**
233 * Check invalid settings rejected -
234 */
235 public function testCreateInvalidURLSettings() {
236 $params = array(
237 'domain_id' => $this->_domainID2,
238 'userFrameworkResourceURL' => 'dfhkd*hfd',
239 );
240 $result = $this->callAPIFailure('setting', 'create', $params);
241 $params = array(
242 'domain_id' => $this->_domainID2,
243 'userFrameworkResourceURL' => 'http://blah.com',
244 );
245 $result = $this->callAPISuccess('setting', 'create', $params);
246 }
247
248 /**
249 * Check getfields works.
250 */
251 public function testCreateInvalidBooleanSettings() {
252 $params = array(
253 'domain_id' => $this->_domainID2,
254 'track_civimail_replies' => 'dfhkdhfd',
255 );
256 $result = $this->callAPIFailure('setting', 'create', $params);
257
258 $params = array('track_civimail_replies' => '0');
259 $result = $this->callAPISuccess('setting', 'create', $params);
260 $getResult = $this->callAPISuccess('setting', 'get', $params);
261 $this->assertEquals(0, $getResult['values'][$this->_currentDomain]['track_civimail_replies']);
262
263 $getResult = $this->callAPISuccess('setting', 'get', $params);
264 $this->assertEquals(0, $getResult['values'][$this->_currentDomain]['track_civimail_replies']);
265 $params = array(
266 'domain_id' => $this->_domainID2,
267 'track_civimail_replies' => '1',
268 );
269 $result = $this->callAPISuccess('setting', 'create', $params);
270 $getResult = $this->callAPISuccess('setting', 'get', $params);
271 $this->assertEquals(1, $getResult['values'][$this->_domainID2]['track_civimail_replies']);
272
273 $params = array(
274 'domain_id' => $this->_domainID2,
275 'track_civimail_replies' => 'TRUE',
276 );
277 $result = $this->callAPISuccess('setting', 'create', $params);
278 $getResult = $this->callAPISuccess('setting', 'get', $params);
279
280 $this->assertEquals(1, $getResult['values'][$this->_domainID2]['track_civimail_replies'], "check TRUE is converted to 1");
281 }
282
283 /**
284 * Check getfields works.
285 */
286 public function testCreateSettingMultipleDomains() {
287 $description = "Shows setting a variable for all domains.";
288
289 $params = array(
290 'domain_id' => 'all',
291 'uniq_email_per_site' => 1,
292 );
293 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__, __FILE__, $description, 'CreateAllDomains');
294
295 $this->assertEquals(1, $result['values'][2]['uniq_email_per_site']);
296 $this->assertEquals(1, $result['values'][1]['uniq_email_per_site']);
297 $this->assertArrayHasKey(3, $result['values'], 'Domain create probably failed Debug this IF domain test is passing');
298 $this->assertEquals(1, $result['values'][3]['uniq_email_per_site'], 'failed to set setting for domain 3.');
299
300 $params = array(
301 'domain_id' => 'all',
302 'return' => 'uniq_email_per_site',
303 );
304 // we'll check it with a 'get'
305 $description = "Shows getting a variable for all domains.";
306 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__, __FILE__, $description, 'GetAllDomains');
307
308 $this->assertEquals(1, $result['values'][2]['uniq_email_per_site']);
309 $this->assertEquals(1, $result['values'][1]['uniq_email_per_site']);
310 $this->assertEquals(1, $result['values'][3]['uniq_email_per_site']);
311
312 $params = array(
313 'domain_id' => array(1, 3),
314 'uniq_email_per_site' => 0,
315 );
316 $description = "Shows setting a variable for specified domains.";
317 $result = $this->callAPIAndDocument('setting', 'create', $params, __FUNCTION__, __FILE__, $description, 'CreateSpecifiedDomains');
318
319 $this->assertEquals(0, $result['values'][3]['uniq_email_per_site']);
320 $this->assertEquals(0, $result['values'][1]['uniq_email_per_site']);
321 $params = array(
322 'domain_id' => array(1, 2),
323 'return' => array('uniq_email_per_site'),
324 );
325 $description = "Shows getting a variable for specified domains.";
326 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__, __FILE__, $description, 'GetSpecifiedDomains');
327 $this->assertEquals(1, $result['values'][2]['uniq_email_per_site']);
328 $this->assertEquals(0, $result['values'][1]['uniq_email_per_site']);
329
330 }
331
332 public function testGetSetting() {
333 $params = array(
334 'domain_id' => $this->_domainID2,
335 'return' => 'uniq_email_per_site',
336 );
337 $description = "Shows get setting a variable for a given domain - if no domain is set current is assumed.";
338
339 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__, __FILE__);
340
341 $params = array(
342 'return' => 'uniq_email_per_site',
343 );
344 $description = "Shows getting a variable for a current domain.";
345 $result = $this->callAPIAndDocument('setting', 'get', $params, __FUNCTION__, __FILE__, $description, 'GetSettingCurrentDomain');
346 $this->assertArrayHasKey(CRM_Core_Config::domainID(), $result['values']);
347 }
348
349 /**
350 * Check that setting defined in extension can be retrieved.
351 */
352 public function testGetExtensionSetting() {
353 $this->hookClass->setHook('civicrm_alterSettingsFolders', array($this, 'setExtensionMetadata'));
354 $data = NULL;
355 // the caching of data to all duplicates the caching of data to the empty string
356 CRM_Core_BAO_Cache::setItem($data, 'CiviCRM setting Spec', 'All');
357 CRM_Core_BAO_Cache::setItem($data, 'CiviCRM setting Specs', 'settingsMetadata__');
358 Civi::cache('settings')->flush();
359 $fields = $this->callAPISuccess('setting', 'getfields', array('filters' => array('group_name' => 'Test Settings')));
360 $this->assertArrayHasKey('test_key', $fields['values']);
361 $this->callAPISuccess('setting', 'create', array('test_key' => 'keyset'));
362 $this->assertEquals('keyset', Civi::settings()->get('test_key'));
363 $result = $this->callAPISuccess('setting', 'getvalue', array('name' => 'test_key', 'group' => 'Test Settings'));
364 $this->assertEquals('keyset', $result);
365 }
366
367 /**
368 * Setting api should set & fetch settings stored in config as well as those in settings table
369 */
370 public function testSetConfigSetting() {
371 $config = CRM_Core_Config::singleton();
372 $this->assertFalse($config->debug == 1);
373
374 $params = array(
375 'domain_id' => $this->_domainID2,
376 'debug_enabled' => 1,
377 );
378 $result = $this->callAPISuccess('setting', 'create', $params);
379
380 $this->assertEquals(1, Civi::settings($this->_domainID2)->get('debug_enabled'));
381
382 CRM_Core_BAO_Domain::setDomain($this->_domainID2);
383 $config = CRM_Core_Config::singleton(TRUE, TRUE);
384 CRM_Core_BAO_Domain::resetDomain();
385 $this->assertEquals(1, $config->debug);
386 }
387
388 /**
389 * Setting api should set & fetch settings stored in config as well as those in settings table
390 */
391 public function testGetConfigSetting() {
392 $settings = $this->callAPISuccess('setting', 'get', array(
393 'name' => 'defaultCurrency',
394 'sequential' => 1,
395 )
396 );
397 $this->assertEquals('USD', $settings['values'][0]['defaultCurrency']);
398 }
399
400 /**
401 * Setting api should set & fetch settings stored in config as well as those in settings table
402 */
403 public function testGetSetConfigSettingMultipleDomains() {
404 $settings = $this->callAPISuccess('setting', 'create', array(
405 'defaultCurrency' => 'USD',
406 'domain_id' => $this->_currentDomain,
407 )
408 );
409 $settings = $this->callAPISuccess('setting', 'create', array(
410 'defaultCurrency' => 'CAD',
411 'domain_id' => $this->_domainID2,
412 )
413 );
414 $settings = $this->callAPISuccess('setting', 'get', array(
415 'return' => 'defaultCurrency',
416 'domain_id' => 'all',
417 )
418 );
419 $this->assertEquals('USD', $settings['values'][$this->_currentDomain]['defaultCurrency']);
420 $this->assertEquals('CAD', $settings['values'][$this->_domainID2]['defaultCurrency'],
421 "second domain (id {$this->_domainID2} ) should be set to CAD. First dom was {$this->_currentDomain} & was USD");
422
423 }
424
425 /**
426 * Use getValue against a config setting.
427 */
428 public function testGetValueConfigSetting() {
429 $params = array(
430 'name' => 'monetaryThousandSeparator',
431 'group' => 'Localization Setting',
432 );
433 $result = $this->callAPISuccess('setting', 'getvalue', $params);
434 $this->assertEquals(',', $result);
435 }
436
437 public function testGetValue() {
438 $params = array(
439 'name' => 'petition_contacts',
440 'group' => 'Campaign Preferences',
441 );
442 $description = "Demonstrates getvalue action - intended for runtime use as better caching than get.";
443
444 $result = $this->callAPIAndDocument('setting', 'getvalue', $params, __FUNCTION__, __FILE__, $description);
445 $this->assertEquals('Petition Contacts', $result);
446 }
447
448 public function testGetDefaults() {
449 $description = "Gets defaults setting a variable for a given domain - if no domain is set current is assumed.";
450
451 $params = array(
452 'name' => 'address_format',
453 );
454 $result = $this->callAPIAndDocument('setting', 'getdefaults', $params, __FUNCTION__, __FILE__, $description, 'GetDefaults');
455 $this->assertEquals("{contact.address_name}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config::domainID()]['address_format']);
456 $params = array('name' => 'mailing_format');
457 $result = $this->callAPISuccess('setting', 'getdefaults', $params);
458 $this->assertEquals("{contact.addressee}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config::domainID()]['mailing_format']);
459 $this->assertArrayHasKey(CRM_Core_Config::domainID(), $result['values']);
460 }
461
462 /**
463 * Function tests reverting a specific parameter.
464 */
465 public function testRevert() {
466 $params = array(
467 'address_format' => 'xyz',
468 'mailing_format' => 'bcs',
469 );
470 $result = $this->callAPISuccess('setting', 'create', $params);
471 $this->assertAPISuccess($result, "in line " . __LINE__);
472 $revertParams = array(
473 'name' => 'address_format',
474 );
475 $result = $this->callAPISuccess('setting', 'get', $params);
476 //make sure it's set
477 $this->assertEquals('xyz', $result['values'][CRM_Core_Config::domainID()]['address_format']);
478 $description = "Demonstrates reverting a parameter to default value.";
479 $result = $this->callAPIAndDocument('setting', 'revert', $revertParams, __FUNCTION__, __FILE__, $description, '');
480 //make sure it's reverted
481 $result = $this->callAPISuccess('setting', 'get', $params);
482 $this->assertEquals("{contact.address_name}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config::domainID()]['address_format']);
483 $params = array(
484 'return' => array('mailing_format'),
485 );
486 $result = $this->callAPISuccess('setting', 'get', $params);
487 //make sure it's unchanged
488 $this->assertEquals('bcs', $result['values'][CRM_Core_Config::domainID()]['mailing_format']);
489 }
490
491 /**
492 * Tests reverting ALL parameters (specific domain)
493 */
494 public function testRevertAll() {
495 $params = array(
496 'address_format' => 'xyz',
497 'mailing_format' => 'bcs',
498 );
499 $result = $this->callAPISuccess('setting', 'create', $params);
500 $revertParams = array();
501 $result = $this->callAPISuccess('setting', 'get', $params);
502 //make sure it's set
503 $this->assertEquals('xyz', $result['values'][CRM_Core_Config::domainID()]['address_format']);
504
505 $this->callAPISuccess('setting', 'revert', $revertParams);
506 //make sure it's reverted
507 $result = $this->callAPISuccess('setting', 'get', array('group' => 'core'));
508 $this->assertEquals("{contact.address_name}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config::domainID()]['address_format']);
509 $this->assertEquals("{contact.addressee}\n{contact.street_address}\n{contact.supplemental_address_1}\n{contact.supplemental_address_2}\n{contact.city}{, }{contact.state_province}{ }{contact.postal_code}\n{contact.country}", $result['values'][CRM_Core_Config::domainID()]['mailing_format']);
510 }
511
512 /**
513 * Settings should respect their defaults
514 */
515 public function testDefaults() {
516 $domparams = array(
517 'name' => 'B Team Domain',
518 );
519 $dom = $this->callAPISuccess('domain', 'create', $domparams);
520 $params = array(
521 'domain_id' => 'all',
522 );
523 $result = $this->callAPISuccess('setting', 'get', $params);
524 $params = array(
525 'address_format' => 'xyz',
526 'mailing_format' => 'bcs',
527 'domain_id' => $this->_domainID2,
528 );
529 $result = $this->callAPISuccess('setting', 'create', $params);
530 $params = array(
531 'domain_id' => $dom['id'],
532 );
533 $result = $this->callAPISuccess('setting', 'get', $params);
534 $this->assertAPISuccess($result, "in line " . __LINE__);
535 $this->assertEquals('Unconfirmed', $result['values'][$dom['id']]['tag_unconfirmed']);
536
537 // The 'fill' operation is no longer necessary, but third parties might still use it, so let's
538 // make sure it doesn't do anything weird (crashing or breaking values).
539 $result = $this->callAPISuccess('setting', 'fill', $params);
540 $this->assertAPISuccess($result, "in line " . __LINE__);
541 $result = $this->callAPISuccess('setting', 'get', $params);
542 $this->assertAPISuccess($result, "in line " . __LINE__);
543 $this->assertArrayHasKey('tag_unconfirmed', $result['values'][$dom['id']]);
544
545 // Setting has NULL default. Not returned.
546 //$this->assertArrayHasKey('extensionsDir', $result['values'][$dom['id']]);
547
548 $this->assertEquals('Unconfirmed', $result['values'][$dom['id']]['tag_unconfirmed']);
549 }
550
551 }