0009918: shared (only free/busy) calendar is showing history
[tine20] / tests / tine20 / Tinebase / Frontend / JsonTest.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Json
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-2014 Metaways Infosystems GmbH (http://www.metaways.de)
10  *
11  */
12
13 /**
14  * Test class for Tinebase_Group
15  */
16 class Tinebase_Frontend_JsonTest extends TestCase
17 {
18     /**
19      * unit under test (UIT)
20      * @var Tinebase_Frontend_Json
21      */
22     protected $_instance;
23
24     /**
25      * @var array test objects
26      */
27     protected $_objects = array();
28     
29     /**
30      * Runs the test methods of this class.
31      */
32     public static function main()
33     {
34         $suite  = new PHPUnit_Framework_TestSuite('Tinebase_Frontend_JsonTest');
35         PHPUnit_TextUI_TestRunner::run($suite);
36     }
37     
38     /**
39      * set up tests
40      *
41      */
42     public function setUp()
43     {
44         parent::setUp();
45         
46         $this->_instance = new Tinebase_Frontend_Json();
47         
48         $this->_objects['record'] = array(
49             'id'        => 1,
50             'model'     => 'Addressbook_Model_Contact',
51             'backend'    => 'Sql',
52         );
53
54         $this->_objects['group'] = new Tinebase_Model_Group(array(
55             'name'            => 'phpunit test group',
56             'description'    => 'phpunit test group'
57         ));
58
59         $this->_objects['role'] = new Tinebase_Model_Role(array(
60             'name'            => 'phpunit test role',
61             'description'    => 'phpunit test role'
62         ));
63
64         $this->_objects['note'] = new Tinebase_Model_Note(array(
65             'note_type_id'      => 1,
66             'note'              => 'phpunit test note',
67             'record_model'      => $this->_objects['record']['model'],
68             'record_backend'    => $this->_objects['record']['backend'],
69         ));
70     }
71     
72     /**
73      * tear down
74      */
75     public function tearDown()
76     {
77         parent::tearDown();
78         
79         // reset tz in core
80         Tinebase_Core::set(Tinebase_Core::USERTIMEZONE, Tinebase_Core::getPreference()->getValue(Tinebase_Preference::TIMEZONE));
81     }
82     
83     /**
84      * try to add a note type
85      */
86     public function testSearchNotes()
87     {
88         $contact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array('n_family' => 'Schulz')));
89         $note = $this->_objects['note'];
90         $note->record_id = $contact->getId();
91         Tinebase_Notes::getInstance()->addNote($note);
92
93         $filter = array(array(
94             'field' => 'query',
95             'operator' => 'contains',
96             'value' => 'phpunit'
97         ), array(
98             'field' => "record_model",
99             'operator' => "equals",
100             'value' => $this->_objects['record']['model']
101         ), array(
102             'field' => 'record_id',
103             'operator' => 'equals',
104             'value' => $contact->getId()
105         ));
106         $paging = array();
107         
108         $notes = $this->_instance->searchNotes($filter, $paging);
109         
110         $this->assertGreaterThan(0, $notes['totalcount']);
111         $found = false;
112         foreach ($notes['results'] as $note) {
113             if ($this->_objects['note']->note === $note['note']) {
114                 $found = true;
115             }
116         }
117         $this->assertTrue($found, 'note not found in notes: ' . print_r($notes['results'], true));
118         
119         // delete note
120         Tinebase_Notes::getInstance()->deleteNotesOfRecord(
121             $this->_objects['record']['model'], 
122             $this->_objects['record']['backend'], 
123             $contact->getId()
124         );
125     }
126     
127     /**
128      * try to delete role and then search
129      */
130     public function testSearchRoles()
131     {
132         $role = Tinebase_Acl_Roles::getInstance()->createRole($this->_objects['role']);
133         
134         $filter = array(array(
135             'field'     => 'query',
136             'operator'     => 'contains',
137             'value'     => 'phpunit test role'
138         ));
139         $paging = array(
140             'start'    => 0,
141             'limit'    => 1
142         );
143         
144         $roles = $this->_instance->searchRoles($filter, $paging);
145         
146         $this->assertGreaterThan(0, $roles['totalcount']);
147         $this->assertEquals($this->_objects['role']->name, $roles['results'][0]['name']);
148         
149         // delete role
150         Tinebase_Acl_Roles::getInstance()->deleteRoles($role->id);
151     }
152     
153     /**
154      * test getCountryList
155      *
156      */
157     public function testGetCountryList()
158     {
159         $list = $this->_instance->getCountryList();
160         $this->assertTrue(count($list['results']) > 200);
161     }
162     
163     /**
164      * test get translations
165      *
166      */
167     public function testGetAvailableTranslations()
168     {
169         $list = $this->_instance->getAvailableTranslations();
170         $this->assertTrue(count($list['results']) > 3);
171     }
172     
173     /**
174      * tests locale fallback
175      */
176     public function testSetLocaleFallback()
177     {
178         // de_LU -> de
179         $this->_instance->setLocale('de_LU', FALSE, FALSE);
180         $this->assertEquals('de', (string)Zend_Registry::get('locale'), 'Fallback to generic german did not succseed');
181         
182         $this->_instance->setLocale('zh', FALSE, FALSE);
183         $this->assertEquals('zh_CN', (string)Zend_Registry::get('locale'), 'Fallback to simplified chinese did not succseed');
184         
185         $this->_instance->setLocale('foo_bar', FALSE, FALSE);
186         $this->assertEquals('en', (string)Zend_Registry::get('locale'), 'Exception fallback to english did not succseed');
187     }
188     
189     /**
190      * test set locale and save it in db
191      */
192     public function testSetLocaleAsPreference()
193     {
194         $oldPreference = Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE};
195         
196         $locale = 'de';
197         $result = $this->_instance->setLocale($locale, TRUE, FALSE);
198         
199         // get config setting from db
200         $preference = Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE};
201         $this->assertEquals($locale, $preference, "Didn't get right locale preference.");
202         
203         // restore old setting
204         Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE} = $oldPreference;
205     }
206
207     /**
208      * test set timezone and save it in db
209      */
210     public function testSetTimezoneAsPreference()
211     {
212         $oldPreference = Tinebase_Core::getPreference()->{Tinebase_Preference::TIMEZONE};
213         
214         $timezone = 'America/Vancouver';
215         $result = $this->_instance->setTimezone($timezone, true);
216         
217         // check json result
218         $this->assertEquals($timezone, $result);
219         
220         // get config setting from db
221         $preference = Tinebase_Core::getPreference()->{Tinebase_Preference::TIMEZONE};
222         $this->assertEquals($timezone, $preference, "Didn't get right timezone preference.");
223         
224         // restore old settings
225         Tinebase_Core::set('userTimeZone', $oldPreference);
226         Tinebase_Core::getPreference()->{Tinebase_Preference::TIMEZONE} = $oldPreference;
227     }
228     
229     /**
230      * get notes types
231      */
232     public function testGetNotesTypes()
233     {
234         $noteTypes = $this->_instance->getNoteTypes();
235         $this->assertTrue($noteTypes['totalcount'] >= 5);
236     }
237     
238     /**
239      * search preferences by application
240      *
241      */
242     public function testSearchPreferences()
243     {
244         // search prefs
245         $result = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter());
246         
247         // check results
248         $this->assertTrue(isset($result['results']));
249         $this->assertGreaterThan(2, $result['totalcount']);
250         
251         //check locale/timezones options
252         foreach ($result['results'] as $pref) {
253             switch($pref['name']) {
254                 case Tinebase_Preference::LOCALE:
255                     $this->assertGreaterThan(10, count($pref['options']));
256                     break;
257                 case Tinebase_Preference::TIMEZONE:
258                     $this->assertGreaterThan(100, count($pref['options']));
259                     break;
260             }
261             // check label and description
262             $this->assertTrue(isset($pref['label']) && !empty($pref['label']));
263             $this->assertTrue(isset($pref['description']) && !empty($pref['description']));
264         }
265     }
266
267     /**
268      * search preferences by application felamimail
269      *
270      */
271     public function testSearchFelamimailPreferences()
272     {
273         // search prefs
274         $result = $this->_instance->searchPreferencesForApplication('Felamimail', '');
275         
276         // check results
277         $this->assertTrue(isset($result['results']));
278         $this->assertGreaterThan(0, $result['totalcount']);
279     }
280
281     /**
282      * search preferences by application
283      *
284      */
285     public function testSearchPreferencesWithOptions()
286     {
287         // add new default pref
288         $pref = $this->_getPreferenceWithOptions();
289         $pref = Tinebase_Core::getPreference()->create($pref);
290         
291         // search prefs
292         $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter());
293         
294         // check results
295         $this->assertTrue(isset($results['results']));
296         $this->assertGreaterThan(3, $results['totalcount']);
297         
298         foreach ($results['results'] as $result) {
299             if ($result['name'] == 'defaultapp') {
300                 $this->assertEquals(Tinebase_Model_Preference::DEFAULT_VALUE, $result['value']);
301                 $this->assertTrue(is_array($result['options']));
302                 $this->assertEquals(3, count($result['options']));
303                 $this->assertContains('option1', $result['options'][1][1]);
304             } else if ($result['name'] == Tinebase_Preference::TIMEZONE) {
305                 $this->assertTrue(is_array($result['options'][0]), 'options should be arrays');
306             }
307         }
308         
309         Tinebase_Core::getPreference()->delete($pref);
310     }
311     
312     /**
313      * search preferences of another user
314      *
315      * @todo add check for the case that searching user has no admin rights
316      */
317     public function testSearchPreferencesOfOtherUsers()
318     {
319         // add new default pref
320         $pref = $this->_getPreferenceWithOptions();
321         $pref->account_id   = '2';
322         $pref->account_type = Tinebase_Acl_Rights::ACCOUNT_TYPE_USER;
323         $pref = Tinebase_Core::getPreference()->create($pref);
324         
325         // search prefs
326         $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(TRUE, FALSE, '2'));
327         
328         // check results
329         $this->assertTrue(isset($results['results']));
330         $this->assertEquals(1, $results['totalcount']);
331     }
332     
333     /**
334      * save preferences for user
335      *
336      * @todo add test for saving of other users prefs and acl check
337      */
338     public function testSavePreferences()
339     {
340         $prefData = $this->_getUserPreferenceData();
341         $this->_instance->savePreferences($prefData, false);
342
343         // search saved prefs
344         $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(FALSE));
345         
346         // check results
347         $this->assertTrue(isset($results['results']));
348         $this->assertGreaterThan(2, $results['totalcount']);
349         
350         $savedPrefData = array();
351         foreach ($results['results'] as $result) {
352             if ($result['name'] == 'timezone') {
353                 $savedPrefData['Tinebase'][$result['name']] = array('value' => $result['value']);
354             
355                 $this->assertTrue(is_array($result['options']), 'options missing');
356                 $this->assertGreaterThan(100, count($result['options']));
357             }
358         }
359         $this->assertEquals($prefData, $savedPrefData);
360     }
361     
362     /**
363      * tests if 'use default' appears in options and if it can be selected and if it changes if default changes
364      */
365     public function testGetSetChangeDefaultPref()
366     {
367         $locale = $this->_getLocalePref();
368         foreach ($locale['options'] as $option) {
369             if ($option[0] == Tinebase_Model_Preference::DEFAULT_VALUE) {
370                 $result = $option;
371                 $defaultString = $option[1];
372             }
373         }
374         
375         $this->assertTrue(isset($defaultString));
376         $this->assertContains('(auto)', $defaultString);
377
378         // set user pref to en first then to 'use default'
379         Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE} = 'en';
380         Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE} = Tinebase_Model_Preference::DEFAULT_VALUE;
381         $this->assertEquals('auto', Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE});
382         
383         // set new default locale
384         $prefData['Tinebase']['default' . $locale['id']] = array('value' => 'de', 'type' => 'default', 'name' => Tinebase_Preference::LOCALE);
385         $this->_instance->savePreferences($prefData, true);
386         
387         $updatedLocale = $this->_getLocalePref();
388         foreach ($updatedLocale['options'] as $option) {
389             if ($option[0] == Tinebase_Model_Preference::DEFAULT_VALUE) {
390                 $result = $option;
391                 $defaultString = $option[1];
392             }
393         }
394         $this->assertEquals(count($locale['options']), count($updatedLocale['options']), 'option count has to be equal');
395         $this->assertContains('(Deutsch)', $defaultString);
396         $this->assertEquals('de', Tinebase_Core::getPreference()->{Tinebase_Preference::LOCALE});
397     }
398     
399     /**
400      * get locale pref
401      */
402     protected function _getLocalePref()
403     {
404         $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter());
405         foreach ($results['results'] as $result) {
406             if ($result['name'] == Tinebase_Preference::LOCALE) {
407                 $locale = $result;
408             }
409         }
410         
411         $this->assertTrue(isset($locale));
412         
413         return $locale;
414     }
415
416     /**
417      * get admin prefs
418      */
419     public function testGetAdminPreferences()
420     {
421         $this->testGetSetChangeDefaultPref();
422         
423         // set new default locale
424         $locale = $this->_getLocalePref();
425         $prefData['Tinebase'][$locale['id']] = array('value' => 'de', 'type' => 'default', 'name' => Tinebase_Preference::LOCALE);
426         $this->_instance->savePreferences($prefData, true);
427         
428         // check as admin
429         $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(FALSE, TRUE));
430         foreach ($results['results'] as $pref) {
431             if ($pref['name'] !== Tinebase_Preference::LOCALE) {
432                 $this->assertEquals(Tinebase_Model_Preference::DEFAULT_VALUE, $pref['value']);
433             } else {
434                 $this->assertEquals(Tinebase_Model_Preference::TYPE_ADMIN, $pref['type']);
435                 $this->assertEquals('de', $pref['value'], print_r($pref, TRUE));
436             }
437         }
438
439         // check as user
440         $locale = $this->_getLocalePref();
441         $this->assertEquals(Tinebase_Model_Preference::TYPE_ADMIN, $locale['type'], 'pref should be of type admin: ' . print_r($locale, TRUE));
442         $this->assertEquals(Tinebase_Model_Preference::DEFAULT_VALUE, $locale['value'], 'pref should be default value: ' . print_r($locale, TRUE));
443     }
444     
445     /**
446      * save admin prefs
447      *
448      */
449     public function testSaveAdminPreferences()
450     {
451         // add new default pref
452         $pref = $this->_getPreferenceWithOptions();
453         $pref = Tinebase_Core::getPreference()->create($pref);
454         
455         $prefData = array();
456         $prefData['Tinebase'][$pref->getId()] = array('value' => 'test', 'type' => 'forced');
457         $this->_instance->savePreferences($prefData, true);
458
459         // search saved prefs
460         $results = $this->_instance->searchPreferencesForApplication('Tinebase', $this->_getPreferenceFilter(TRUE));
461         
462         // check results
463         $this->assertTrue(isset($results['results']));
464         $this->assertEquals(1, $results['totalcount']);
465         $this->assertEquals($prefData['Tinebase'][$pref->getId()]['value'], $results['results'][0]['value']);
466         $this->assertEquals($prefData['Tinebase'][$pref->getId()]['type'], $results['results'][0]['type']);
467     }
468     
469     /**
470      * save state and load it with registry data
471      */
472     public function testSaveAndGetState()
473     {
474         $testData = array(
475             'bla'   => 'blubb',
476             'zzing' => 'zzang'
477         );
478         
479         foreach ($testData as $key => $value) {
480             Tinebase_State::getInstance()->setState($key, $value);
481         }
482         
483         $stateInfo = Tinebase_State::getInstance()->loadStateInfo();
484         
485         $this->assertEquals($testData, $stateInfo);
486     }
487     
488     /**
489      * test get all registry data
490      * 
491      * @return void
492      * 
493      * @see 0007934: change pw button active even if it is not allowed
494      * @see 0008310: apps should be sorted the other way round in menu
495      */
496     public function testGetAllRegistryData()
497     {
498         $registryData = $this->_instance->getAllRegistryData();
499         $currentUser = Tinebase_Core::getUser();
500         
501         $this->assertEquals($currentUser->toArray(), $registryData['Tinebase']['currentAccount']);
502         $this->assertEquals(
503             Addressbook_Controller_Contact::getInstance()->getContactByUserId($currentUser->getId())->toArray(), 
504             $registryData['Tinebase']['userContact']
505         );
506         $this->assertEquals(TRUE, $registryData['Tinebase']['config']['changepw']['value'], 'changepw should be TRUE');
507         
508         Tinebase_Config::getInstance()->set('changepw', 0);
509         $registryData = $this->_instance->getAllRegistryData();
510         $changepwValue = $registryData['Tinebase']['config']['changepw']['value'];
511         $this->assertEquals(FALSE, $changepwValue, 'changepw should be (bool) false');
512         $this->assertTrue(is_bool($changepwValue), 'changepw should be (bool) false: ' . var_export($changepwValue, TRUE));
513         
514         $userApps = $registryData['Tinebase']['userApplications'];
515         $this->assertEquals('Admin', $userApps[0]['name'], 'first app should be Admin: ' . print_r($userApps, TRUE));
516     }
517     
518     /**
519      * testGetUserProfile
520      */
521     public function testGetUserProfile()
522     {
523         $profile = $this->_instance->getUserProfile(Tinebase_Core::getUser()->getId());
524
525         $this->assertTrue(is_array($profile));
526         $this->assertTrue((isset($profile['userProfile']) || array_key_exists('userProfile', $profile)));
527         $this->assertTrue(is_array($profile['userProfile']));
528         $this->assertTrue((isset($profile['readableFields']) || array_key_exists('readableFields', $profile)));
529         $this->assertTrue(is_array($profile['readableFields']));
530         $this->assertTrue((isset($profile['updateableFields']) || array_key_exists('updateableFields', $profile)));
531         $this->assertTrue(is_array($profile['updateableFields']));
532         
533         // try to get user profile of different user
534         $this->setExpectedException('Tinebase_Exception_AccessDenied');
535         
536         $sclever = array_value('sclever',Zend_Registry::get('personas'));
537         $this->_instance->getUserProfile($sclever->getId());
538     }
539     
540     /**
541      * testGetUserProfileConfig
542      */
543     public function testGetUserProfileConfig()
544     {
545         $config = $this->_instance->getUserProfileConfig();
546         
547         $this->assertTrue(is_array($config));
548         $this->assertTrue((isset($config['possibleFields']) || array_key_exists('possibleFields', $config)));
549         $this->assertTrue(is_array($config['possibleFields']));
550         $this->assertTrue((isset($config['readableFields']) || array_key_exists('readableFields', $config)));
551         $this->assertTrue(is_array($config['readableFields']));
552         $this->assertTrue((isset($config['updateableFields']) || array_key_exists('updateableFields', $config)));
553         $this->assertTrue(is_array($config['updateableFields']));
554     }
555     
556     /**
557      * testSetUserProfileConfig
558      */
559     public function testSetUserProfileConfig()
560     {
561         $config = $this->_instance->getUserProfileConfig();
562         
563         $idx = array_search('n_prefix', $config['readableFields']);
564         if ($idx !== false) {
565             unset ($config['readableFields'][$idx]);
566         }
567         
568         $idx = array_search('tel_home', $config['updateableFields']);
569         if ($idx !== false) {
570             unset ($config['updateableFields'][$idx]);
571         }
572         
573         $this->_instance->setUserProfileConfig($config);
574     }
575     
576     /**
577      * testupdateUserProfile
578      */
579     public function testUpdateUserProfile()
580     {
581         $profile = $this->_instance->getUserProfile(Tinebase_Core::getUser()->getId());
582         $profileData = $profile['userProfile'];
583         
584         $this->assertFalse(array_search('n_prefix', $profileData));
585         
586         $profileData['tel_home'] = 'mustnotchange';
587         $profileData['email_home'] = 'email@userprofile.set';
588         
589         $this->_instance->updateUserProfile($profileData);
590         
591         $updatedProfile = $this->_instance->getUserProfile(Tinebase_Core::getUser()->getId());
592         $updatedProfileData = $updatedProfile['userProfile'];
593         $this->assertNotEquals('mustnotchange', $updatedProfileData['tel_home']);
594         $this->assertEquals('email@userprofile.set', $updatedProfileData['email_home']);
595     }
596     
597     /**
598      * testGetSaveApplicationConfig
599      */
600     public function testGetSaveApplicationConfig()
601     {
602         $config = $this->_instance->getConfig('Admin');
603         $this->assertGreaterThan(0, count($config));
604         
605         $data = array(
606             'id'        => 'Admin',
607             'settings'  => Admin_Controller::getInstance()->getConfigSettings(),
608         );
609         
610         $newConfig = $this->_instance->saveConfig($data);
611         
612         $this->assertEquals($config, $newConfig);
613     }
614     
615     /******************** protected helper funcs ************************/
616     
617     /**
618      * get preference filter
619      *
620      * @param bool $_savedPrefs
621      * @return array
622      */
623     protected function _getPreferenceFilter($_savedPrefs = FALSE, $_adminPrefs = FALSE, $_userId = NULL)
624     {
625         if ($_userId === NULL) {
626             $_userId = Tinebase_Core::getUser()->getId();
627         }
628         
629         $result = array(
630             array(
631                 'field' => 'account', 
632                 'operator' => 'equals', 
633                 'value' => array(
634                     'accountId'     => ($_adminPrefs) ? 0 : $_userId,
635                     'accountType'   => ($_adminPrefs) 
636                         ? Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE 
637                         : Tinebase_Acl_Rights::ACCOUNT_TYPE_USER
638                 )
639             )
640         );
641
642         if ($_savedPrefs) {
643             $result[] = array(
644                 'field' => 'name', 
645                 'operator' => 'contains', 
646                 'value' => 'defaultapp'
647             );
648         }
649         
650         return $result;
651     }
652
653     /**
654      * get preference data for testSavePreferences()
655      *
656      * @return array
657      */
658     protected function _getUserPreferenceData()
659     {
660         return array(
661             'Tinebase' => array(
662                 'timezone' => array('value' => 'Europe/Amsterdam'),
663             )
664         );
665     }
666     
667     /**
668      * get preference with options
669      *
670      * @return Tinebase_Model_Preference
671      */
672     protected function _getPreferenceWithOptions()
673     {
674         return new Tinebase_Model_Preference(array(
675             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Tinebase')->getId(),
676             'name'              => 'defaultapp',
677             'value'             => 'value1',
678             'account_id'        => '0',
679             'account_type'      => Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE,
680             'type'              => Tinebase_Model_Preference::TYPE_ADMIN,
681             'options'           => '<?xml version="1.0" encoding="UTF-8"?>
682                 <options>
683                     <option>
684                         <label>option1</label>
685                         <value>value1</value>
686                     </option>
687                     <option>
688                         <label>option2</label>
689                         <value>value2</value>
690                     </option>
691                 </options>'
692         ));
693     }
694 }