7 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
8 * @author Philipp Schüle <p.schuele@metaways.de>
9 * @copyright Copyright (c) 2007-2015 Metaways Infosystems GmbH (http://www.metaways.de)
16 require_once dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'TestHelper.php';
19 * Test class for Tinebase_Frontend_Json
21 class Tinebase_Frontend_JsonTest extends TestCase
24 * unit under test (UIT)
25 * @var Tinebase_Frontend_Json
30 * @var array test objects
32 protected $_objects = array();
38 public function setUp()
42 $this->_instance = new Tinebase_Frontend_Json();
44 $this->_objects['record'] = array(
46 'model' => 'Addressbook_Model_Contact',
50 $this->_objects['group'] = new Tinebase_Model_Group(array(
51 'name' => 'phpunit test group',
52 'description' => 'phpunit test group'
55 $this->_objects['role'] = new Tinebase_Model_Role(array(
56 'name' => 'phpunit test role',
57 'description' => 'phpunit test role'
60 $this->_objects['note'] = new Tinebase_Model_Note(array(
62 'note' => 'phpunit test note',
63 'record_model' => $this->_objects['record']['model'],
64 'record_backend' => $this->_objects['record']['backend'],
71 public function tearDown()
76 Tinebase_Core::set(Tinebase_Core::USERTIMEZONE, Tinebase_Core::getPreference()->getValue(Tinebase_Preference::TIMEZONE));
80 * try to add a note type
82 public function testSearchNotes()
84 $contact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array('n_family' => 'Schulz')));
85 $note = $this->_objects['note'];
86 $note->record_id = $contact->getId();
87 Tinebase_Notes::getInstance()->addNote($note);
89 $filter = array(array(
91 'operator' => 'contains',
94 'field' => "record_model",
95 'operator' => "equals",
96 'value' => $this->_objects['record']['model']
98 'field' => 'record_id',
99 'operator' => 'equals',
100 'value' => $contact->getId()
104 $notes = $this->_instance->searchNotes($filter, $paging);
106 $this->assertGreaterThan(0, $notes['totalcount']);
108 foreach ($notes['results'] as $note) {
109 if ($this->_objects['note']->note === $note['note']) {
113 $this->assertTrue($found, 'note not found in notes: ' . print_r($notes['results'], true));
116 Tinebase_Notes::getInstance()->deleteNotesOfRecord(
117 $this->_objects['record']['model'],
118 $this->_objects['record']['backend'],
124 * try to delete role and then search
126 public function testSearchRoles()
128 $role = Tinebase_Acl_Roles::getInstance()->createRole($this->_objects['role']);
130 $filter = array(array(
132 'operator' => 'contains',
133 'value' => 'phpunit test role'
140 $roles = $this->_instance->searchRoles($filter, $paging);
142 $this->assertGreaterThan(0, $roles['totalcount']);
143 $this->assertEquals($this->_objects['role']->name, $roles['results'][0]['name']);
146 Tinebase_Acl_Roles::getInstance()->deleteRoles($role->id);
150 * test getCountryList
153 public function testGetCountryList()
155 $list = $this->_instance->getCountryList();
156 $this->assertTrue(count($list['results']) > 200);
160 * test get translations
163 public function testGetAvailableTranslations()
165 $list = $this->_instance->getAvailableTranslations();
166 $this->assertTrue(count($list['results']) > 3);
170 * tests locale fallback
172 public function testSetLocaleFallback()
175 $this->_instance->setLocale('de_LU', FALSE, FALSE);
176 $this->assertEquals('de', (string)Zend_Registry::get('locale'), 'Fallback to generic german did not succseed');
178 $this->_instance->setLocale('zh', FALSE, FALSE);
179 $this->assertEquals('zh_CN', (string)Zend_Registry::get('locale'), 'Fallback to simplified chinese did not succseed');
181 $this->_instance->setLocale('foo_bar', FALSE, FALSE);
182 $this->assertEquals('en', (string)Zend_Registry::get('locale'), 'Exception fallback to english did not succseed');
186 * test set locale and save it in db
188 public function testSetLocaleAsPreference()
190 $oldPreference = Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE};
193 $result = $this->_instance->setLocale($locale, TRUE, FALSE);
195 // get config setting from db
196 $preference = Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE};
197 $this->assertEquals($locale, $preference, "Didn't get right locale preference.");
199 // restore old setting
200 Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE} = $oldPreference;
204 * test set timezone and save it in db
206 public function testSetTimezoneAsPreference()
208 $oldPreference = Tinebase_Core::getPreference()->{Tinebase_Preference::TIMEZONE};
210 $timezone = 'America/Vancouver';
211 $result = $this->_instance->setTimezone($timezone, true);
214 $this->assertEquals($timezone, $result);
216 // get config setting from db
217 $preference = Tinebase_Core::getPreference()->{Tinebase_Preference::TIMEZONE};
218 $this->assertEquals($timezone, $preference, "Didn't get right timezone preference.");
220 // restore old settings
221 Tinebase_Core::set(Tinebase_Core::USERTIMEZONE, $oldPreference);
222 Tinebase_Core::getPreference()->{Tinebase_Preference::TIMEZONE} = $oldPreference;
228 public function testGetNotesTypes()
230 $noteTypes = $this->_instance->getNoteTypes();
231 $this->assertTrue($noteTypes['totalcount'] >= 5);
235 * toogle advanced search preference
237 public function testAdvancedSearchToogle()
239 $toogle = $this->_instance->toogleAdvancedSearch(1);
241 $this->assertEquals($toogle, 1);
242 $this->assertEquals(Tinebase_Core::getPreference()->getValue(Tinebase_Preference::ADVANCED_SEARCH, 0), 1);
246 * search preferences by application
249 public function testSearchPreferences()
252 $result = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter());
255 $this->assertTrue(isset($result['results']));
256 $this->assertGreaterThan(2, $result['totalcount']);
258 //check locale/timezones options
259 foreach ($result['results'] as $pref) {
260 switch($pref['name']) {
261 case Tinebase_Preference::LOCALE:
262 $this->assertGreaterThan(10, count($pref['options']));
264 case Tinebase_Preference::TIMEZONE:
265 $this->assertGreaterThan(100, count($pref['options']));
268 // check label and description
269 $this->assertTrue(isset($pref['label']) && !empty($pref['label']));
270 $this->assertTrue(isset($pref['description']) && !empty($pref['description']));
275 * search preferences by application
278 public function testSearchPreferencesWithOptions()
280 // add new default pref
281 $pref = $this->_getPreferenceWithOptions();
282 $pref = Tinebase_Core::getPreference()->create($pref);
285 $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter());
288 $this->assertTrue(isset($results['results']));
289 $this->assertGreaterThan(3, $results['totalcount']);
291 foreach ($results['results'] as $result) {
292 if ($result['name'] == 'defaultapp') {
293 $this->assertEquals(Tinebase_Model_Preference::DEFAULT_VALUE, $result['value']);
294 $this->assertTrue(is_array($result['options']));
295 $this->assertEquals(3, count($result['options']));
296 $this->assertContains('option1', $result['options'][1][1]);
297 } else if ($result['name'] == Tinebase_Preference::TIMEZONE) {
298 $this->assertTrue(is_array($result['options'][0]), 'options should be arrays');
302 Tinebase_Core::getPreference()->delete($pref);
306 * search preferences of another user
308 * @todo add check for the case that searching user has no admin rights
310 public function testSearchPreferencesOfOtherUsers()
312 // add new default pref
313 $pref = $this->_getPreferenceWithOptions();
314 $pref->account_id = '2';
315 $pref->account_type = Tinebase_Acl_Rights::ACCOUNT_TYPE_USER;
316 $pref = Tinebase_Core::getPreference()->create($pref);
319 $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(TRUE, FALSE, '2'));
322 $this->assertTrue(isset($results['results']));
323 $this->assertEquals(1, $results['totalcount']);
327 * save preferences for user
329 * @todo add test for saving of other users prefs and acl check
331 public function testSavePreferences()
333 $prefData = $this->_getUserPreferenceData();
334 $this->_instance->savePreferences($prefData, false);
336 // search saved prefs
337 $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(FALSE));
340 $this->assertTrue(isset($results['results']));
341 $this->assertGreaterThan(2, $results['totalcount']);
343 $savedPrefData = array();
344 foreach ($results['results'] as $result) {
345 if ($result['name'] == 'timezone') {
346 $savedPrefData['Tinebase'][$result['name']] = array('value' => $result['value']);
348 $this->assertTrue(is_array($result['options']), 'options missing');
349 $this->assertGreaterThan(100, count($result['options']));
352 $this->assertEquals($prefData, $savedPrefData);
356 * tests if 'use default' appears in options and if it can be selected and if it changes if default changes
358 public function testGetSetChangeDefaultPref()
360 $locale = $this->_getLocalePref();
361 foreach ($locale['options'] as $option) {
362 if ($option[0] == Tinebase_Model_Preference::DEFAULT_VALUE) {
364 $defaultString = $option[1];
368 $this->assertTrue(isset($defaultString));
369 $this->assertContains('(auto)', $defaultString);
371 // set user pref to en first then to 'use default'
372 Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE} = 'en';
373 Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE} = Tinebase_Model_Preference::DEFAULT_VALUE;
374 $this->assertEquals('auto', Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE});
376 // set new default locale
377 $prefData['Tinebase']['default' . $locale['id']] = array('value' => 'de', 'type' => 'default', 'name' => Tinebase_Preference::LOCALE);
378 $this->_instance->savePreferences($prefData, true);
380 $updatedLocale = $this->_getLocalePref();
381 foreach ($updatedLocale['options'] as $option) {
382 if ($option[0] == Tinebase_Model_Preference::DEFAULT_VALUE) {
384 $defaultString = $option[1];
387 $this->assertEquals(count($locale['options']), count($updatedLocale['options']), 'option count has to be equal');
388 $this->assertContains('(Deutsch)', $defaultString);
389 $this->assertEquals('de', Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE});
395 protected function _getLocalePref()
397 $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter());
398 foreach ($results['results'] as $result) {
399 if ($result['name'] == Tinebase_Preference::LOCALE) {
404 $this->assertTrue(isset($locale));
412 public function testGetAdminPreferences()
414 $this->testGetSetChangeDefaultPref();
416 // set new default locale
417 $locale = $this->_getLocalePref();
418 $prefData['Tinebase'][$locale['id']] = array('value' => 'de', 'type' => 'default', 'name' => Tinebase_Preference::LOCALE);
419 $this->_instance->savePreferences($prefData, true);
422 $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(FALSE, TRUE));
423 foreach ($results['results'] as $pref) {
424 if ($pref['name'] !== Tinebase_Preference::LOCALE) {
425 $this->assertEquals(Tinebase_Model_Preference::DEFAULT_VALUE, $pref['value']);
427 $this->assertEquals(Tinebase_Model_Preference::TYPE_ADMIN, $pref['type']);
428 $this->assertEquals('de', $pref['value'], print_r($pref, TRUE));
433 $locale = $this->_getLocalePref();
434 $this->assertEquals(Tinebase_Model_Preference::TYPE_ADMIN, $locale['type'], 'pref should be of type admin: ' . print_r($locale, TRUE));
435 $this->assertEquals(Tinebase_Model_Preference::DEFAULT_VALUE, $locale['value'], 'pref should be default value: ' . print_r($locale, TRUE));
442 public function testSaveAdminPreferences()
444 // add new default pref
445 $pref = $this->_getPreferenceWithOptions();
446 $pref = Tinebase_Core::getPreference()->create($pref);
449 $prefData['Tinebase'][$pref->getId()] = array('value' => 'test', 'type' => 'forced');
450 $this->_instance->savePreferences($prefData, true);
452 // search saved prefs
453 $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(TRUE));
456 $this->assertTrue(isset($results['results']));
457 $this->assertEquals(1, $results['totalcount']);
458 $this->assertEquals($prefData['Tinebase'][$pref->getId()]['value'], $results['results'][0]['value']);
459 $this->assertEquals($prefData['Tinebase'][$pref->getId()]['type'], $results['results'][0]['type']);
463 * save state and load it with registry data
465 public function testSaveAndGetState()
472 foreach ($testData as $key => $value) {
473 Tinebase_State::getInstance()->setState($key, $value);
476 $stateInfo = Tinebase_State::getInstance()->loadStateInfo();
478 $this->assertEquals($testData, $stateInfo);
482 * test get all registry data
486 * @see 0007934: change pw button active even if it is not allowed
487 * @see 0008310: apps should be sorted the other way round in menu
488 * @see 0009130: Can't open login page on Ubuntu "due to a temporary overloading"
489 * @see 0012188: add copyOmitFields to modelconfig
490 * @see 0012364: generalize import/export and allow to configure via modelconfig
492 public function testGetAllRegistryData()
494 $registryData = $this->_instance->getAllRegistryData();
495 $currentUser = Tinebase_Core::getUser();
497 $this->assertTrue(isset($registryData['Tinebase']['currentAccount']), print_r($registryData['Tinebase'], true));
498 $this->assertEquals($currentUser->toArray(), $registryData['Tinebase']['currentAccount']);
500 Addressbook_Controller_Contact::getInstance()->getContactByUserId($currentUser->getId())->toArray(),
501 $registryData['Tinebase']['userContact']
503 $this->assertEquals(TRUE, $registryData['Tinebase']['config']['changepw']['value'], 'changepw should be TRUE');
505 Tinebase_Config::getInstance()->set('changepw', 0);
506 $registryData = $this->_instance->getAllRegistryData();
507 $changepwValue = $registryData['Tinebase']['config']['changepw']['value'];
508 $this->assertEquals(FALSE, $changepwValue, 'changepw should be (bool) false');
509 $this->assertTrue(is_bool($changepwValue), 'changepw should be (bool) false: ' . var_export($changepwValue, TRUE));
511 $userApps = $registryData['Tinebase']['userApplications'];
512 $this->assertEquals('Admin', $userApps[0]['name'], 'first app should be Admin: ' . print_r($userApps, TRUE));
514 $locale = Tinebase_Core::getLocale();
515 $symbols = Zend_Locale::getTranslationList('symbols', $locale);
516 $this->assertEquals($symbols['decimal'], $registryData['Tinebase']['decimalSeparator']);
518 if (Sales_Config::getInstance()->featureEnabled(Sales_Config::FEATURE_INVOICES_MODULE)) {
519 $configuredSalesModels = array_keys($registryData['Sales']['models']);
520 $this->assertTrue(in_array('Invoice', $configuredSalesModels), 'Invoices is missing from configured models: '
521 . print_r($configuredSalesModels, true));
522 $copyOmitFields = array(
529 $copyOmitFields = array(
536 $this->assertTrue(isset($registryData['Timetracker']['models']['Timeaccount']['copyOmitFields']), 'Timeaccount copyOmitFields empty/missing');
537 $this->assertEquals($copyOmitFields, $registryData['Timetracker']['models']['Timeaccount']['copyOmitFields']);
538 $this->assertTrue(is_array(($registryData['Timetracker']['relatableModels'][0])), 'relatableModels needs to be an numbered array');
540 $this->assertTrue(isset($registryData['Inventory']['models']['InventoryItem']['export']), 'no InventoryItem export config found: '
541 . print_r($registryData['Inventory']['models']['InventoryItem'], true));
542 $this->assertTrue(isset($registryData['Inventory']['models']['InventoryItem']['export']['supportedFormats']));
543 $this->assertEquals(array('csv', 'ods'), $registryData['Inventory']['models']['InventoryItem']['export']['supportedFormats']);
544 $this->assertTrue(isset($registryData['Inventory']['models']['InventoryItem']['import']));
548 * test get all registry data with persistent filters
552 * @see 0009610: shared favorites acl
554 public function testGetAllPersistentFilters()
556 $this->markTestSkipped('@see 0010192: fix persistent filter tests');
558 $registryData = $this->_instance->getAllRegistryData();
560 $filterData = $registryData['Tinebase']['persistentFilters'];
561 $this->assertTrue($filterData['totalcount'] > 10);
562 $this->assertTrue(isset($filterData['results'][0]['grants']), 'grants are missing');
563 $grants = $filterData['results'][0]['grants'];
564 $this->assertTrue($grants[0]['readGrant']);
566 // check if accounts are resolved
567 $this->assertTrue(is_array($grants[0]['account_name']), 'account should be resolved: ' . print_r($grants[0], true));
573 public function testGetUserProfile()
575 $profile = $this->_instance->getUserProfile(Tinebase_Core::getUser()->getId());
577 $this->assertTrue(is_array($profile));
578 $this->assertTrue((isset($profile['userProfile']) || array_key_exists('userProfile', $profile)));
579 $this->assertTrue(is_array($profile['userProfile']));
580 $this->assertTrue((isset($profile['readableFields']) || array_key_exists('readableFields', $profile)));
581 $this->assertTrue(is_array($profile['readableFields']));
582 $this->assertTrue((isset($profile['updateableFields']) || array_key_exists('updateableFields', $profile)));
583 $this->assertTrue(is_array($profile['updateableFields']));
585 // try to get user profile of different user
586 $this->setExpectedException('Tinebase_Exception_AccessDenied');
588 $sclever = Tinebase_Helper::array_value('sclever',Zend_Registry::get('personas'));
589 $this->_instance->getUserProfile($sclever->getId());
593 * testGetUserProfileConfig
595 public function testGetUserProfileConfig()
597 $config = $this->_instance->getUserProfileConfig();
599 $this->assertTrue(is_array($config));
600 $this->assertTrue((isset($config['possibleFields']) || array_key_exists('possibleFields', $config)));
601 $this->assertTrue(is_array($config['possibleFields']));
602 $this->assertTrue((isset($config['readableFields']) || array_key_exists('readableFields', $config)));
603 $this->assertTrue(is_array($config['readableFields']));
604 $this->assertTrue((isset($config['updateableFields']) || array_key_exists('updateableFields', $config)));
605 $this->assertTrue(is_array($config['updateableFields']));
609 * testSetUserProfileConfig
611 public function testSetUserProfileConfig()
613 $config = $this->_instance->getUserProfileConfig();
615 $idx = array_search('n_prefix', $config['readableFields']);
616 if ($idx !== false) {
617 unset ($config['readableFields'][$idx]);
620 $idx = array_search('tel_home', $config['updateableFields']);
621 if ($idx !== false) {
622 unset ($config['updateableFields'][$idx]);
625 $this->_instance->setUserProfileConfig($config);
629 * testupdateUserProfile
631 public function testUpdateUserProfile()
633 $profile = $this->_instance->getUserProfile(Tinebase_Core::getUser()->getId());
634 $profileData = $profile['userProfile'];
636 $this->assertFalse(array_search('n_prefix', $profileData));
638 $profileData['tel_home'] = 'mustnotchange';
639 $profileData['email_home'] = 'email@userprofile.set';
641 $this->_instance->updateUserProfile($profileData);
643 $updatedProfile = $this->_instance->getUserProfile(Tinebase_Core::getUser()->getId());
644 $updatedProfileData = $updatedProfile['userProfile'];
645 $this->assertNotEquals('mustnotchange', $updatedProfileData['tel_home']);
646 $this->assertEquals('email@userprofile.set', $updatedProfileData['email_home']);
650 * testGetSaveApplicationConfig
652 public function testGetSaveApplicationConfig()
654 $config = $this->_instance->getConfig('Admin');
655 $this->assertGreaterThan(0, count($config));
659 'settings' => Admin_Controller::getInstance()->getConfigSettings(),
662 $newConfig = $this->_instance->saveConfig($data);
664 $this->assertEquals($config, $newConfig);
668 * testChangeUserAccount
670 * @see 0009984: allow to change user role
672 public function testChangeUserAccount()
674 // allow test user to sign in as sclever
675 Tinebase_Config::getInstance()->set(Tinebase_Config::ROLE_CHANGE_ALLOWED, new Tinebase_Config_Struct(array(
676 Tinebase_Core::getUser()->accountLoginName => array('sclever')
679 $sclever = $this->_personas['sclever'];
680 $result = $this->_instance->changeUserAccount('sclever');
682 $this->assertEquals(array('success' => true), $result);
684 // make sure, we are sclever
685 $this->assertEquals('sclever', Tinebase_Core::getUser()->accountLoginName);
686 $this->assertEquals('sclever', Tinebase_Session::getSessionNamespace()->currentAccount->accountLoginName);
688 // reset to original user
689 Tinebase_Controller::getInstance()->initUser($this->_originalTestUser, /* $fixCookieHeader = */ false);
690 Tinebase_Session::getSessionNamespace()->userAccountChanged = false;
694 * testOmitPersonalTagsOnSearch
696 * @see 0010732: add "use personal tags" right to all applications
698 public function testOmitPersonalTagsOnSearch()
700 $personalTag = $this->_getTag(Tinebase_Model_Tag::TYPE_PERSONAL);
701 Tinebase_Tags::getInstance()->createTag($personalTag);
703 $this->_removeRoleRight('Addressbook', Tinebase_Acl_Rights::USE_PERSONAL_TAGS);
705 'application' => 'Addressbook',
706 'grant' => Tinebase_Model_TagRight::VIEW_RIGHT,
707 'type' => Tinebase_Model_Tag::TYPE_PERSONAL
709 $result = $this->_instance->searchTags($filter, array());
711 $this->assertEquals(0, $result['totalCount']);
714 /******************** protected helper funcs ************************/
717 * get preference filter
719 * @param bool $_savedPrefs
722 protected function _getPreferenceFilter($_savedPrefs = FALSE, $_adminPrefs = FALSE, $_userId = NULL)
724 if ($_userId === NULL) {
725 $_userId = Tinebase_Core::getUser()->getId();
730 'field' => 'account',
731 'operator' => 'equals',
733 'accountId' => ($_adminPrefs) ? 0 : $_userId,
734 'accountType' => ($_adminPrefs)
735 ? Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE
736 : Tinebase_Acl_Rights::ACCOUNT_TYPE_USER
744 'operator' => 'contains',
745 'value' => 'defaultapp'
753 * get preference data for testSavePreferences()
757 protected function _getUserPreferenceData()
761 'timezone' => array('value' => 'Europe/Amsterdam'),
767 * get preference with options
769 * @return Tinebase_Model_Preference
771 protected function _getPreferenceWithOptions()
773 return new Tinebase_Model_Preference(array(
774 'application_id' => Tinebase_Application::getInstance()->getApplicationByName('Tinebase')->getId(),
775 'name' => 'defaultapp',
778 'account_type' => Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE,
779 'type' => Tinebase_Model_Preference::TYPE_ADMIN,
780 'options' => '<?xml version="1.0" encoding="UTF-8"?>
783 <label>option1</label>
784 <value>value1</value>
787 <label>option2</label>
788 <value>value2</value>