0013214: allow to set fixed calendars as user preference
[tine20] / tests / tine20 / Tinebase / PreferenceTest.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * @package     Tinebase
6  * @license     http://www.gnu.org/licenses/agpl.html
7  * @copyright   Copyright (c) 2009-2014 Metaways Infosystems GmbH (http://www.metaways.de)
8  * @author      Philipp Schüle <p.schuele@metaways.de>
9  * 
10  */
11
12 /**
13  * Test helper
14  */
15 require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'TestHelper.php';
16
17 /**
18  * Test class for Tinebase_PreferenceTest
19  */
20 class Tinebase_PreferenceTest extends TestCase
21 {
22     /**
23      * unit under test (UIT)
24      * @var Tinebase_Preference
25      */
26     protected $_instance;
27     
28     /**
29      * Sets up the fixture.
30      * This method is called before a test is executed.
31      *
32      * @access protected
33      */
34     protected function setUp()
35     {
36         $this->_instance = Tinebase_Core::getPreference();
37         Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
38     }
39     
40     /**
41      * Tears down the fixture
42      * This method is called after a test is executed.
43      *
44      * @access protected
45      */
46     protected function tearDown()
47     {
48         Tinebase_TransactionManager::getInstance()->rollBack();
49     }
50     
51     /**
52      * get default preference
53      *
54      */
55     public function testGetDefaultPreference()
56     {
57         // delete default pref first
58         $preferences = $this->_instance->getMultipleByProperty(Tinebase_Preference::TIMEZONE);
59         foreach ($preferences as $preference) {
60             if (
61                 $preference->type === Tinebase_Model_Preference::TYPE_DEFAULT 
62                 || (
63                     $preference->account_id === Tinebase_Core::getUser()->getId()
64                     && $preference->account_type === Tinebase_Acl_Rights::ACCOUNT_TYPE_USER
65                 )
66             ) {
67                 $this->_instance->delete($preference);
68             }
69         }
70         
71         $prefValue = $this->_instance->getValue(Tinebase_Preference::TIMEZONE);
72         
73         $this->assertEquals('Europe/Berlin', $prefValue);
74
75         // test get interceptor
76         $prefValue = $this->_instance->{Tinebase_Preference::TIMEZONE};
77         
78         $this->assertEquals('Europe/Berlin', $prefValue);
79         
80         // restore preferences
81         foreach ($preferences as $preference) {
82             $this->_instance->create($preference);
83         }
84     }
85     
86     /**
87      * test set timezone pref
88      *
89      */
90     public function testSetPreference()
91     {
92         $newValue = 'Europe/Nicosia';
93         $this->_instance->setValue(Tinebase_Preference::TIMEZONE, $newValue);
94
95         $prefValue = $this->_instance->getValue(Tinebase_Preference::TIMEZONE);
96         $this->assertEquals($newValue, $prefValue);
97         
98         // reset old default value (with set interceptor)
99         $this->_instance->{Tinebase_Preference::TIMEZONE} = 'Europe/Berlin';
100         $prefValue = $this->_instance->getValue(Tinebase_Preference::TIMEZONE);
101         $this->assertEquals('Europe/Berlin', $prefValue);
102     }
103
104     /**
105      * test get default value
106      *
107      */
108     public function testGetDefaultPreferenceValue()
109     {
110         $defaultValue = 'Shangri-La';
111         $prefValue = $this->_instance->getValue('SomeNonexistantPref', $defaultValue);
112         
113         $this->assertEquals($defaultValue, $prefValue);
114     }
115     
116     /**
117      * test forced preference
118      *
119      * @todo use existant pref
120      */
121     public function testForcedPreference()
122     {
123         $forcedPrefName ='locale';
124         $forcedPref = $this->_createTestPreference($forcedPrefName);
125         
126         // set pref for user
127         $this->_instance->testForcedPref = 'user value';
128         
129         $pref = $this->_instance->$forcedPrefName;
130         
131         $this->assertEquals($forcedPref->value, $pref);
132     }
133
134     /**
135      * test public only preference, try to force it -> should throw exception
136      *
137      */
138     public function testPublicOnlyPreference()
139     {
140         $prefName ='testForcedPref';
141         $pref = new Tinebase_Model_Preference(array(
142             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Tinebase')->getId(),
143             'name'              => $prefName,
144             'value'             => 'value',
145             'account_id'        => '0',
146             'account_type'      => Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE,
147             'type'              => Tinebase_Model_Preference::TYPE_FORCED,
148             'personal_only'     => TRUE
149         ));
150         
151         // try to force pref
152         $this->setExpectedException('Tinebase_Exception_UnexpectedValue');
153         $pref = $this->_instance->create($pref);
154     }
155     
156     /**
157      * test get users with pref function
158      *
159      */
160     public function testGetUsersWithPref()
161     {
162         $this->_instance->{Tinebase_Preference::TIMEZONE} = 'Europe/Nicosia';
163         $userIds = $this->_instance->getUsersWithPref(Tinebase_Preference::TIMEZONE, 'Europe/Berlin');
164         
165         $this->assertTrue(! in_array(Setup_Core::getUser()->getId(), $userIds), 'admin user should have other timezone setting');
166         $this->assertGreaterThan(4, count($userIds), 'too few users found');
167         
168         $this->_instance->{Tinebase_Preference::TIMEZONE} = 'Europe/Berlin';
169     }
170     
171     /**
172      * test search for preferences and check if preference that is not defined is removed from result
173      */
174     public function testSearchPreferences()
175     {
176         $testPref = $this->_createTestPreference('testPref');
177         
178         $result = $this->_instance->search($this->_getPreferenceFilter(Tinebase_Model_Preference::TYPE_FORCED));
179         
180         $this->assertTrue(count($result) == 0);
181     }
182     
183     /**
184      * test search for preferences for anyone of calendar
185      * 
186      * @see 0005298: wrong default favorite in admin pref panel
187      */
188     public function testSearchCalendarPreferencesForAnyone()
189     {
190         $tasksPersistentFilter = Tinebase_PersistentFilter::getInstance()->getPreferenceValues('Tasks');
191         $this->assertTrue(isset($tasksPersistentFilter[5]), 'could not find tasks persistent filter pref: ' . print_r($tasksPersistentFilter, true));
192         
193         $json = new Tinebase_Frontend_Json();
194         $filter = $this->_getPreferenceFilter(NULL, Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE);
195         $result = $json->searchPreferencesForApplication('Tasks', $filter->toArray());
196         $prefData = $result['results'];
197         $prefToSave = array();
198         foreach ($prefData as $pref) {
199             if ($pref['name'] === Tasks_Preference::DEFAULTPERSISTENTFILTER) {
200                 $prefToSave[$pref['id']] = array(
201                     'name'  => Tasks_Preference::DEFAULTPERSISTENTFILTER,
202                     'value' => $tasksPersistentFilter[5][0],
203                     'type'  => Tinebase_Model_Preference::TYPE_ADMIN,
204                 );
205             }
206         }
207         Tinebase_Core::getPreference('Tasks')->saveAdminPreferences($prefToSave);
208
209         $result = $json->searchPreferencesForApplication('Calendar', $filter->toArray());
210         
211         $this->assertGreaterThan(0, $result['totalcount']);
212         
213         $filterPref = NULL;
214         foreach ($result['results'] as $pref) {
215             if ($pref['name'] === Calendar_Preference::DEFAULTPERSISTENTFILTER) {
216                 $filterPref = $pref;
217             }
218         }
219         $this->assertTrue($filterPref !== NULL);
220         $this->assertEquals(Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(), $filterPref['application_id'], print_r($filterPref, TRUE));
221     }
222     
223     /**
224      * testDeleteAdminPrefByChangingUserPref
225      * 
226      * @see 0008052: Change in user preference alters admin preferences
227      */
228     public function testDeleteAdminPrefByChangingUserPref()
229     {
230         $defaultValue = 'Europe/Nicosia';
231         $defaultPref = $this->_createTestPreference(Tinebase_Preference::TIMEZONE, 'Europe/Nicosia', Tinebase_Model_Preference::TYPE_DEFAULT);
232
233         $this->_instance->{Tinebase_Preference::TIMEZONE} = 'Europe/Berlin';
234         
235         $defaultPref = $this->_instance->get($defaultPref->getId());
236         $this->assertEquals($defaultValue, $defaultPref->value, 'defaultpref value overwritten: ' . print_r($defaultPref->toArray(), TRUE));
237     }
238     
239     /**
240      * testSetForcedDefaultPref
241      * 
242      * @see 0009606: preferences: forcing current default value is not working
243      */
244     public function testSetForcedDefaultPref()
245     {
246         $defaultPref = $this->_instance->getApplicationPreferenceDefaults(Tinebase_Preference::TIMEZONE);
247         $this->_instance->saveAdminPreferences(array(
248             $defaultPref->getId() => array(
249                 'type'  => Tinebase_Model_Preference::TYPE_FORCED,
250                 'value' => 0,
251                 'name'  => Tinebase_Preference::TIMEZONE
252             )
253         ));
254         
255         $result = $this->_instance->search();
256         $pref = $result->filter('name', Tinebase_Preference::TIMEZONE)->getFirstRecord();
257         
258         $this->assertTrue($pref !== null);
259         $this->assertEquals(Tinebase_Model_Preference::TYPE_FORCED, $pref->type);
260         $this->assertEquals(0, $pref->value);
261     }
262
263     /**
264      * testSetLockedPref
265      *
266      * @see 0011178: allow to lock preferences for individual users
267      */
268     public function testSetLockedPref()
269     {
270         $tzPref = $this->_instance->getApplicationPreferenceDefaults(Tinebase_Preference::TIMEZONE);
271         $tzPref->type = Tinebase_Model_Preference::TYPE_USER;
272         $tzPref->locked = true;
273         $tzPref->id = null;
274         $tzPref->account_id = Tinebase_Core::getUser()->getId();
275         $tzPref->account_type = Tinebase_Acl_Rights::ACCOUNT_TYPE_USER;
276         $tzPref = $this->_instance->create($tzPref);
277
278         $result = $this->_instance->search();
279         $pref = $result->filter('name', Tinebase_Preference::TIMEZONE)->getFirstRecord();
280
281         $this->assertTrue($pref !== null);
282         $this->assertEquals(Tinebase_Model_Preference::TYPE_USER, $pref->type);
283         $this->assertEquals(true, $pref->locked);
284
285         try {
286             $this->_instance->setValue(Tinebase_Preference::TIMEZONE, 'Europe/Berlin');
287             $this->fail('it is not allowed to set locked preference: ' . print_r($tzPref->toArray(), true));
288         } catch (Tinebase_Exception_AccessDenied $tead) {
289             $this->assertEquals('You are not allowed to change the locked preference.', $tead->getMessage());
290         }
291     }
292
293     /**
294      * @see 0013214: allow to set fixed calendars as user preference
295      */
296     public function testSetFixedCalendarsPreference()
297     {
298         $personalContainer = $this->_getPersonalContainer('Calendar');
299         $data =
300           array (
301             'Calendar' =>
302             array (
303               'fixedCalendars' =>
304               array (
305                 'value' =>
306                 array (
307                   0 =>
308                       $personalContainer->toArray()
309                 ),
310               ),
311             ),
312         );
313
314         $frontend = new Tinebase_Frontend_Json();
315         $result = $frontend->savePreferences($data, /* adminMode */ false);
316         self::assertEquals('success', $result['status']);
317
318         $preferences = $frontend->searchPreferencesForApplication('Calendar', array());
319         $fixedCalendarsPref = false;
320         foreach ($preferences['results'] as $preference) {
321             if ($preference['name'] == 'fixedCalendars') {
322                 $fixedCalendarsPref = $preference;
323             }
324         }
325         self::assertTrue(is_array($fixedCalendarsPref), print_r($preferences['results'], true));
326         self::assertEquals(1, count($fixedCalendarsPref['value']), 'did not find personal container in value: '
327             . print_r($fixedCalendarsPref, true));
328         $container = $fixedCalendarsPref['value'][0];
329         self::assertTrue(is_array($container));
330         self::assertEquals($personalContainer->getId(), $container['id']);
331         self::assertTrue(isset($fixedCalendarsPref['uiconfig']), 'uiconfig missing: '
332             . print_r($fixedCalendarsPref, true));
333         $fixedCalendarIds = Calendar_Controller_Event::getInstance()->getFixedCalendarIds();
334         self::assertTrue(in_array($personalContainer->getId(), $fixedCalendarIds));
335     }
336
337     /******************** protected helper funcs ************************/
338     
339     /**
340      * get preference filter
341      *
342      * @param string $type
343      * @param string $accountType
344      * @return Tinebase_Model_PreferenceFilter
345      */
346     protected function _getPreferenceFilter($type = Tinebase_Model_Preference::TYPE_USER, $accountType = Tinebase_Acl_Rights::ACCOUNT_TYPE_USER)
347     {
348         $filterData = array(
349             array(
350                 'field' => 'account', 
351                 'operator' => 'equals', 
352                 'value' => array(
353                     'accountId'     => ($accountType === Tinebase_Acl_Rights::ACCOUNT_TYPE_USER) ? Tinebase_Core::getUser()->getId() : 0,
354                     'accountType'   => $accountType
355                 )
356             ),
357         );
358         
359         if ($type !== NULL) {
360             $filterData[] = array(
361                 'field' => 'type', 
362                 'operator' => 'equals', 
363                 'value' => $type
364             );
365         }
366         
367         return new Tinebase_Model_PreferenceFilter($filterData);
368     }
369     
370     /**
371      * create test preference
372      * 
373      * @param string $prefName
374      * @param string $value,
375      * @param string $type
376      * @return Tinebase_Model_Preference
377      */
378     protected function _createTestPreference($prefName, $value = 'forced value', $type = Tinebase_Model_Preference::TYPE_FORCED)
379     {
380         $pref = new Tinebase_Model_Preference(array(
381             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Tinebase')->getId(),
382             'name'              => $prefName,
383             'value'             => $value,
384             'account_id'        => '0',
385             'account_type'      => Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE,
386             'type'              => $type
387         ));
388         $pref = $this->_instance->create($pref);
389         
390         return $pref;
391     }
392 }