0009768: Use ModelConfig for Timetracker models
[tine20] / tests / tine20 / Timetracker / ControllerTest.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * this test class mainly tests the timeaccount grants and the controller functions
6  * 
7  * @package     Timetracker
8  * @license     http://www.gnu.org/licenses/agpl.html
9  * @copyright   Copyright (c) 2008-2014 Metaways Infosystems GmbH (http://www.metaways.de)
10  * @author      Philipp Schüle <p.schuele@metaways.de>
11  * 
12  * @todo        add test for manage_billable
13  */
14
15 /**
16  * Test class for Timetracker_ControllerTest
17  */
18 class Timetracker_ControllerTest extends TestCase
19 {
20     /**
21      * @var Timetracker_Controller_Timeaccount
22      */
23     protected $_timeaccountController = array();
24     
25     /**
26      * @var Timetracker_Controller_Timesheet
27      */
28     protected $_timesheetController = array();
29     
30     /**
31      * role rights
32      *
33      * @var array
34      */
35     protected $_roleRights = array();
36
37     /**
38      * objects
39      *
40      * @var array
41      */
42     protected $_objects = array();
43     
44     /**
45      * Sets up the fixture.
46      * This method is called before a test is executed.
47      *
48      * @access protected
49      */
50     protected function setUp()
51     {
52         parent::setUp();
53         
54         $this->_timeaccountController = Timetracker_Controller_Timeaccount::getInstance();
55         $this->_timesheetController = Timetracker_Controller_Timesheet::getInstance();
56
57         // get timesheet
58         $this->_objects['timesheet'] = $this->_getTimesheet();
59         $this->_objects['timeaccount'] = $this->_timeaccountController->get($this->_objects['timesheet']->timeaccount_id);
60         
61         Tinebase_Acl_Roles::getInstance()->resetClassCache();
62         
63         $this->_roleRights = self::removeManageAllRight();
64     }
65     
66     /**
67      * remove MANAGE_ALL & ADMIN for Timetracker right
68      * 
69      * @return array
70      */
71     public static function removeManageAllRight()
72     {
73         $role = Tinebase_Acl_Roles::getInstance()->getRoleByName('admin role');
74         $app = Tinebase_Application::getInstance()->getApplicationByName('Timetracker');
75         
76         $currentRights = Tinebase_Acl_Roles::getInstance()->getRoleRights($role->getId());
77         $rightsWithoutManageAll = array();
78         foreach ($currentRights as $right) {
79             if ($right['right'] != Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS
80             && !($right['application_id'] == $app->getId() && $right['right'] == 'admin')
81             ) {
82                 $rightsWithoutManageAll[] = $right;
83             }
84         }
85         Tinebase_Acl_Roles::getInstance()->setRoleRights($role->getId(), $rightsWithoutManageAll);
86         return $currentRights;
87     }
88
89     /**
90      * Tears down the fixture
91      * This method is called after a test is executed.
92      *
93      * @access protected
94      */
95     protected function tearDown()
96     {
97         parent::tearDown();
98         
99         Tinebase_Acl_Roles::getInstance()->resetClassCache();
100     }
101     
102     /************ test functions follow **************/
103
104     /**
105      * test to create TS with book_own grant
106      *
107      */
108     public function testNoGrantsValidatorDefaultValue()
109     {
110         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
111             'account_id'    => Tinebase_Core::getUser()->getId(),
112             'account_type'  => 'user',
113             Timetracker_Model_TimeaccountGrants::VIEW_ALL      => TRUE,
114         )));
115         
116         $this->assertEquals($grants->{Timetracker_Model_TimeaccountGrants::VIEW_ALL}, array(TRUE));
117         $this->assertEquals($grants->{Timetracker_Model_TimeaccountGrants::BOOK_OWN}, array(FALSE));
118         $this->assertEquals($grants->{Timetracker_Model_TimeaccountGrants::BOOK_ALL}, array(FALSE));
119     }
120     
121     /**
122      * test to create TS with book_own grant
123      *
124      */
125     public function testNoGrantsTS()
126     {
127         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
128             'account_id'    => Tinebase_Core::getUser()->getId(),
129             'account_type'  => 'user',
130             Timetracker_Model_TimeaccountGrants::VIEW_ALL        => TRUE,
131             Timetracker_Model_TimeaccountGrants::MANAGE_BILLABLE => TRUE
132         )));
133         
134         $this->_grantTestHelper($grants, 'create', 'Exception');
135     }
136     
137     /**
138      * test to create TS with book_own grant
139      *
140      */
141     public function testBookOwnGrantTS()
142     {
143         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
144             'account_id'    => Tinebase_Core::getUser()->getId(),
145             'account_type'  => 'user',
146             Timetracker_Model_TimeaccountGrants::BOOK_OWN      => TRUE,
147         )));
148         
149         $this->_grantTestHelper($grants);
150     }
151     
152     /**
153      * test to create TS with book_all grant
154      *
155      */
156     public function testBookAllGrantTS()
157     {
158         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
159             'account_id'    => Tinebase_Core::getUser()->getId(),
160             'account_type'  => 'user',
161             Timetracker_Model_TimeaccountGrants::BOOK_ALL      => TRUE,
162         )));
163         
164         $this->_grantTestHelper($grants);
165     }
166     
167     /**
168      * test to create not billable TS with manage_billable grant
169      *
170      */
171     public function testManageClearingGrantTS()
172     {
173         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
174             'account_id'      => Tinebase_Core::getUser()->getId(),
175             'account_type'    => 'user',
176             //Tinebase_Model_Grants::GRANT_ADMIN    => TRUE,
177             Timetracker_Model_TimeaccountGrants::BOOK_ALL        => TRUE,
178             Timetracker_Model_TimeaccountGrants::MANAGE_BILLABLE => TRUE,
179         )));
180         
181         $ts = clone $this->_objects['timesheet'];
182         $ts->is_billable = 0;
183         
184         $this->_grantTestHelper($grants, 'create', NULL, $ts);
185     }
186
187     /**
188      * test to create not billable TS without manage_billable grant
189      *
190      */
191     public function testManageClearingGrantTSNotSet()
192     {
193         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
194             'account_id'      => Tinebase_Core::getUser()->getId(),
195             'account_type'    => 'user',
196             //Tinebase_Model_Grants::GRANT_ADMIN    => TRUE,
197             Timetracker_Model_TimeaccountGrants::BOOK_ALL        => TRUE,
198             Timetracker_Model_TimeaccountGrants::MANAGE_BILLABLE => FALSE,
199         )));
200         
201         $ts = clone $this->_objects['timesheet'];
202         $ts->is_billable = 0;
203         
204         $this->_grantTestHelper($grants, 'create', 'Exception', $ts);
205     }
206     
207     /**
208      * test to create TS with manage_all grant
209      *
210      */
211     public function testManageAllGrantTS()
212     {
213         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
214             'account_id'    => Tinebase_Core::getUser()->getId(),
215             'account_type'  => 'user',
216             Tinebase_Model_Grants::GRANT_ADMIN    => TRUE,
217         )));
218         
219         $this->_grantTestHelper($grants);
220     }
221     
222     /**
223      * test to search TAs (view_all)
224      *
225      */
226     public function testSearchTA()
227     {
228         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
229             'account_id'    => Tinebase_Core::getUser()->getId(),
230             'account_type'  => 'user',
231             Timetracker_Model_TimeaccountGrants::VIEW_ALL      => TRUE,
232         )));
233         
234         $this->_grantTestHelper($grants, 'searchTA', 1);
235     }
236
237     /**
238      * test to search TAs (no grants)
239      *
240      */
241     public function testSearchTAWithNoRights()
242     {
243         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
244             'account_id'    => Tinebase_Core::getUser()->getId(),
245             'account_type'  => 'user',
246         )));
247         
248         $this->_grantTestHelper($grants, 'searchTA', 0);
249     }
250
251     /**
252      * test to search TAs (book_own)
253      *
254      */
255     public function testSearchTABookable()
256     {
257         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
258             'account_id'    => Tinebase_Core::getUser()->getId(),
259             'account_type'  => 'user',
260             Timetracker_Model_TimeaccountGrants::BOOK_OWN      => TRUE,            
261         )));
262         
263         $this->_grantTestHelper($grants, 'search_bookable', 1);
264     }
265
266     /**
267      * test to search TSs (view_all)
268      *
269      */
270     public function testSearchTS()
271     {
272         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
273             'account_id'    => Tinebase_Core::getUser()->getId(),
274             'account_type'  => 'user',
275             Timetracker_Model_TimeaccountGrants::BOOK_OWN      => TRUE,
276             Timetracker_Model_TimeaccountGrants::VIEW_ALL      => TRUE,
277         )));
278         
279         $this->_grantTestHelper($grants, 'searchTS', 1);
280
281         $filter = $this->_getTimesheetFilter();
282
283                 $be = new Timetracker_Backend_Timesheet();
284         $result = $be->search($filter)->toArray();
285         $this->assertArrayHasKey('is_billable_combined', $result[0]);
286
287         $result = $this->_timesheetController->search($filter)->toArray();
288         $this->assertArrayHasKey('is_billable_combined', $result[0]);
289     }
290
291     /**
292      * test to search TSs for export
293      *
294      */
295     public function testSearchTSExport()
296     {
297         $ts = $this->_timesheetController->create($this->_objects['timesheet']);
298         
299         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
300             'account_id'    => Tinebase_Core::getUser()->getId(),
301             'account_type'  => 'user',
302             Tinebase_Model_Grants::GRANT_EXPORT   => TRUE,
303         )));
304         
305         $this->_grantTestHelper($grants, 'searchTSExport', 1, $ts);
306     }
307     
308     /**
309      * try to add a Timesheet exceeding deadline
310      *
311      */
312     public function testAddTimesheetExceedingDeadline()
313     {
314         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
315             'account_id'    => Tinebase_Core::getUser()->getId(),
316             'account_type'  => 'user',
317             Timetracker_Model_TimeaccountGrants::BOOK_OWN      => TRUE,
318         )));
319         
320         $this->_grantTestHelper($grants, 'create_deadline');
321     }
322     
323     /************ protected helper funcs *************/
324     
325     /**
326      * try to add a Timesheet with different grants
327      * 
328      * @param   Tinebase_Record_RecordSet $_grants
329      * @param   string $_action
330      * @param   mixed $_expect
331      * @param   Timetracker_Model_Timesheet
332      */
333     protected function _grantTestHelper($_grants, $_action = 'create', $_expect = NULL, $_ts = NULL)
334     {
335         // take default ts?
336         $ts = $_ts ? $_ts : $this->_objects['timesheet'];
337         
338         // remove BOOK_OWN + BOOK_ALL + ADMIN grant
339         Timetracker_Model_TimeaccountGrants::setTimeaccountGrants(
340             $this->_objects['timeaccount'],
341             $_grants,
342             TRUE
343         );
344         
345         // try to create timesheet
346         switch ($_action) {
347             case 'create':
348                 if ($_expect === 'Exception') {
349                     $this->setExpectedException('Tinebase_Exception_AccessDenied');
350                     $this->_timesheetController->create($ts);
351                 } else {
352                     $ts = $this->_timesheetController->create($ts);
353                     $this->assertEquals(Tinebase_Core::getUser()->getId(), $ts->created_by);
354                 }
355                 break;
356             case 'create_deadline':
357                 // date is before deadline
358                 $date = new Tinebase_DateTime();
359                 $date->sub(8, Tinebase_DateTime::MODIFIER_DAY);
360                 $ts->start_date = $date->toString('Y-m-d');
361                 $this->setExpectedException('Timetracker_Exception_Deadline');
362                 $this->_timesheetController->create($ts);
363                 break;
364             case 'search_bookable':
365                 $filter = $this->_getTimeaccountFilter(TRUE);
366                 $result = $this->_timeaccountController->search($filter);
367                 $this->assertEquals($_expect, count($result));
368                 break;
369             case 'searchTA':
370                 $filter = $this->_getTimeaccountFilter();
371                 $result = $this->_timeaccountController->search($filter);
372                 $this->assertEquals($_expect, count($result));
373                 break;
374             case 'searchTS':
375                 $filter = $this->_getTimesheetFilter();
376                 $ts = $this->_timesheetController->create($ts);
377                 $result = $this->_timesheetController->search($filter);
378                 $this->assertEquals($_expect, count($result));
379                 break;
380             case 'searchTSExport':
381                 $filter = $this->_getTimesheetFilter();
382                 $result = $this->_timesheetController->search($filter, NULL, FALSE, FALSE, 'export');
383                 $this->assertEquals($_expect, count($result));
384                 break;
385             default:
386                 echo "nothing tested.";
387         }
388
389         // delete (set delete grant first)
390         $grants = new Tinebase_Record_RecordSet('Timetracker_Model_TimeaccountGrants', array(array(
391             'account_id'    => Tinebase_Core::getUser()->getId(),
392             'account_type'  => 'user',
393             Timetracker_Model_TimeaccountGrants::MANAGE_BILLABLE  => TRUE,
394             Tinebase_Model_Grants::GRANT_ADMIN      => TRUE,
395             Timetracker_Model_TimeaccountGrants::BOOK_ALL      => TRUE,
396             Timetracker_Model_TimeaccountGrants::BOOK_OWN      => TRUE,
397             Timetracker_Model_TimeaccountGrants::VIEW_ALL      => TRUE,
398             Tinebase_Model_Grants::GRANT_EXPORT  => TRUE,
399         )));
400         Timetracker_Model_TimeaccountGrants::setTimeaccountGrants(
401             $this->_objects['timeaccount'],
402             $grants,
403             TRUE
404         );
405     }
406     
407     /**
408      * get Timesheet
409      * @param array $data
410      * @return Timetracker_Model_Timeaccount
411      */
412     protected function _getTimeaccount($data = array())
413     {
414         return new Timetracker_Model_Timeaccount(array_merge(array(
415             'title'         => Tinebase_Record_Abstract::generateUID(),
416             'description'   => 'blabla',
417             'is_open'       => 1,
418             'deadline'      => Timetracker_Model_Timeaccount::DEADLINE_LASTWEEK
419         ),$data), TRUE);
420     }
421     
422     /**
423      * get Timesheet (create timeaccount as well)
424      *
425      * @return Timetracker_Model_Timesheet
426      */
427     protected function _getTimesheet()
428     {
429         $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->create($this->_getTimeaccount());
430         
431         return new Timetracker_Model_Timesheet(array(
432             'account_id'        => Tinebase_Core::getUser()->getId(),
433             'timeaccount_id'    => $timeaccount->getId(),
434             'description'       => 'blabla',
435             'start_date'        => Tinebase_DateTime::now()->toString('Y-m-d'),
436             'duration'          => 30,
437         ), TRUE);
438     }
439
440     /**
441      * get Timeaccount filter
442      *
443      * @return Timetracker_Model_TimeaccountFilter
444      */
445     protected function _getTimeaccountFilter($bookable = FALSE)
446     {
447         $result = new Timetracker_Model_TimeaccountFilter(array(
448             array(
449                 'field' => 'description', 
450                 'operator' => 'contains', 
451                 'value' => 'blabla'
452             ),
453             array(
454                 'field' => 'containerType', 
455                 'operator' => 'equals', 
456                 'value' => Tinebase_Model_Container::TYPE_SHARED
457             ),  
458         ));
459         
460         if ($bookable) {
461             $result->isBookable = TRUE;
462         }
463         
464         return ($result);
465     }
466     
467     /**
468      * get Timesheet filter
469      *
470      * @return array
471      */
472     protected function _getTimesheetFilter()
473     {
474         return new Timetracker_Model_TimesheetFilter(array(
475             array(
476                 'field' => 'query', 
477                 'operator' => 'contains', 
478                 'value' => 'blabla'
479             ),
480         ));
481     }
482     
483     /**
484      * tests the findTimesheetsByTimeaccountAndPeriod method of the timesheet controller
485      */
486     public function testFindTimesheetsByTimeaccountAndPeriod()
487     {
488         $i=0;
489         
490         $now = Tinebase_DateTime::now();
491         $data = array('account_id' => Tinebase_Core::getUser()->getId(), 'is_cleared' => true, 'timeaccount_id' => $this->_objects['timeaccount']->getId(), 'description' => 'test', 'duration' => 1, 'title' => 'test');
492         
493         while ($i<10) {
494             $data['start_date'] = $now->addHour(1);
495             $this->_timesheetController->create(new Timetracker_Model_Timesheet($data));
496             $i++;
497         }
498         
499         $sdate = Tinebase_DateTime::now();
500         $sdate->subDay(1);
501         $edate = $now->addDay(1);
502         
503         $result = $this->_timesheetController->findTimesheetsByTimeaccountAndPeriod($this->_objects['timeaccount']->getId(), $sdate, $edate);
504         
505         $this->assertEquals(10, count($result));
506     }
507 }