Merge branch '2015.11-develop' into 2016.11
[tine20] / tests / tine20 / Tinebase / ApplicationTest.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * @package     Tinebase
6  * @subpackage  Application
7  * @license     http://www.gnu.org/licenses/agpl.html
8  * @copyright   Copyright (c) 2008-2014 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Philipp Schuele <p.schuele@metaways.de>
10  */
11
12 /**
13  * Test class for Tinebase_Group
14  */
15 class Tinebase_ApplicationTest extends TestCase
16 {
17     /**
18      * @var array test objects
19      */
20     protected $objects = array();
21
22     /**
23      * Runs the test methods of this class.
24      *
25      * @access public
26      * @static
27      */
28     public static function main()
29     {
30         $suite  = new PHPUnit_Framework_TestSuite('Tinebase_ApplicationTest');
31         PHPUnit_TextUI_TestRunner::run($suite);
32     }
33     
34     protected function tearDown()
35     {
36         parent::tearDown();
37         
38         // delete an non existing application to trigger file system cache cleanup
39         Tinebase_Application::getInstance()->deleteApplication('1234567890123456789012345678901234567890');
40     }
41     
42     /**
43      * try to get all application rights
44      */
45     public function testGetAllRights()
46     {
47         $application = Tinebase_Application::getInstance()->getApplicationByName('Admin');
48         $rights = Tinebase_Application::getInstance()->getAllRights($application->getId());
49         
50         //print_r($rights);
51         
52         $this->assertGreaterThan(0, count($rights));
53
54         $application = Tinebase_Application::getInstance()->getApplicationByName('Addressbook');
55         $rights = Tinebase_Application::getInstance()->getAllRights($application->getId());
56         
57         //print_r($rights);
58         
59         $this->assertGreaterThan(0, count($rights));
60     }
61     
62     /**
63      * test create application
64      * 
65      * @return Tinebase_Model_Application
66      */
67     public function testAddApplication()
68     {
69         $application = Tinebase_Application::getInstance()->addApplication(new Tinebase_Model_Application(array(
70             'name'      => Tinebase_Record_Abstract::generateUID(25),
71             'status'    => Tinebase_Application::ENABLED,
72             'order'     => 99,
73             'version'   => 1
74         )));
75         
76         $this->assertTrue($application instanceof Tinebase_Model_Application);
77         
78         return $application;
79     }
80     
81     /**
82      * test update application
83      * 
84      * @return Tinebase_Model_Application
85      */
86     public function testUpdateApplication()
87     {
88         $application = $this->testAddApplication();
89         $application->name = Tinebase_Record_Abstract::generateUID(25);
90         
91         $testApplication = Tinebase_Application::getInstance()->updateApplication($application);
92         
93         $this->assertEquals($testApplication->name, $application->name);
94         
95         return $application;
96     }
97     
98     /**
99      * test update application
100      * 
101      * @return Tinebase_Model_Application
102      */
103     public function testDeleteApplication()
104     {
105         $application = $this->testAddApplication();
106         
107         Tinebase_Application::getInstance()->deleteApplication($application);
108         
109         $this->setExpectedException('Tinebase_Exception_NotFound');
110         
111         Tinebase_Application::getInstance()->getApplicationById($application);
112     }
113     
114     /**
115      * test get application by name and id
116      * 
117      * @return void
118      */
119     public function testGetApplicationById()
120     {
121         $application = $this->testAddApplication();
122         
123         $applicationByName = Tinebase_Application::getInstance()->getApplicationByName($application->name);
124         $applicationById = Tinebase_Application::getInstance()->getApplicationById($application->getId());
125         
126         $this->assertTrue($applicationByName instanceof Tinebase_Model_Application);
127         $this->assertTrue($applicationById instanceof Tinebase_Model_Application);
128         $this->assertEquals($application, $applicationByName);
129         $this->assertEquals($application, $applicationById);
130     }
131     
132     /**
133      * test get application by invalid id
134      * 
135      * @return void
136      */
137     public function testGetApplicationByInvalidId()
138     {
139         $this->setExpectedException('Tinebase_Exception_NotFound');
140         
141         Tinebase_Application::getInstance()->getApplicationById(Tinebase_Record_Abstract::generateUID());
142     }
143     
144     /**
145      * test get applications
146      * 
147      * @return void
148      */
149     public function testGetApplications()
150     {
151         $applications = Tinebase_Application::getInstance()->getApplications('Ad');
152         
153         $this->assertInstanceOf('Tinebase_Record_RecordSet', $applications);
154         $this->assertGreaterThanOrEqual(2, count($applications));
155     }
156     
157     /**
158      * test get applications by state
159      * 
160      * @return void
161      */
162     public function testGetApplicationByState()
163     {
164         $application = $this->testAddApplication();
165         
166         $applications = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
167         
168         $this->assertInstanceOf('Tinebase_Record_RecordSet', $applications);
169         $this->assertGreaterThanOrEqual(2, count($applications));
170         $this->assertContains($application->id, $applications->id);
171         
172         
173         Tinebase_Application::getInstance()->setApplicationState($application, Tinebase_Application::DISABLED);
174         $applications = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
175         $this->assertNotContains($application->id, $applications->id);
176         
177         
178         $application2 = $this->testAddApplication();
179         $applications = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
180         $this->assertContains($application2->id, $applications->id);
181         
182         
183         Tinebase_Application::getInstance()->deleteApplication($application2);
184         $applications = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
185         $this->assertNotContains($application2->id, $applications->id);
186         
187         
188         Tinebase_Application::getInstance()->setApplicationState($application, Tinebase_Application::ENABLED);
189         $applications = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
190         $this->assertContains($application->id, $applications->id);
191     }
192     
193     /**
194      * test get applications by invalid state
195      * 
196      * @return void
197      */
198     public function testGetApplicationByInvalidState()
199     {
200         $this->setExpectedException('Tinebase_Exception_InvalidArgument');
201         
202         $applications = Tinebase_Application::getInstance()->getApplicationsByState('foobar');
203     }
204     
205     /**
206      * test get application by invalid id
207      * 
208      * @return void
209      */
210     public function testGetApplicationByInvalidName()
211     {
212         $this->setExpectedException('Tinebase_Exception_NotFound');
213         
214         Tinebase_Application::getInstance()->getApplicationByName(Tinebase_Record_Abstract::generateUID());
215     }
216     
217     /**
218      * test get application total count
219      * 
220      * @return void
221      */
222     public function testGetTotalApplicationCount()
223     {
224         $result = Tinebase_Application::getInstance()->getTotalApplicationCount();
225         
226         $this->assertGreaterThanOrEqual(3, $result);
227     }
228     
229     /**
230      * Test length name for table name and column name (Oracle Database limitation)
231      * Table name is less than 30 at least since Oracle 7
232      * 
233      * @see 0007452: use json encoded array for saving of policy settings
234      */
235     public function testSetupXML()
236     {
237         $applications = Tinebase_Application::getInstance()->getApplications();
238         
239         foreach ($applications->name as $applicationName) {
240             // skip ActiveSync
241             // @todo remove that when #7452 is resolved
242             if ($applicationName === 'ActiveSync') {
243                 continue;
244             }
245             
246             $xml = Setup_Controller::getInstance()->getSetupXml($applicationName);
247             if (isset($xml->tables)) {
248                 foreach ($xml->tables[0] as $tableXML) {
249                     $table = Setup_Backend_Schema_Table_Factory::factory('Xml', $tableXML);
250                     $currentTable = $table->name;
251                     $this->assertLessThan(30, strlen($currentTable), $applicationName." -> ". $table->name . "  (" . strlen($currentTable).")");
252                     foreach ($table->fields as $field) {
253                         $this->assertLessThan(31, strlen($field->name), $applicationName." -> ". $table->name . "  (" . strlen($field->name).")");
254                     }
255                 }
256             }
257         }
258     }
259
260     /**
261      * Test
262      */
263     public function testGetModelsOfAllApplications()
264     {
265         $models = Tinebase_Application::getInstance()->getModelsOfAllApplications();
266         $applications = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
267         $appNames = $applications->name;
268
269         $expectedData = array(
270             'ActiveSync' => array(
271                 'ActiveSync_Model_Policy',
272                 'ActiveSync_Model_Device',
273             ),
274             'Addressbook' => array(
275                 'Addressbook_Model_Salutation',
276                 'Addressbook_Model_List',
277                 'Addressbook_Model_ListRole',
278                 'Addressbook_Model_ListMemberRole',
279                 'Addressbook_Model_Contact',
280             ),
281             'Admin' => array(
282                 'Admin_Model_Config',
283                 'Admin_Model_SambaMachine',
284             ),
285             'Calendar' => array(
286                 'Calendar_Model_Resource',
287                 'Calendar_Model_iMIP',
288                 'Calendar_Model_Rrule',
289                 'Calendar_Model_AttendeeRole',
290                 'Calendar_Model_Event',
291                 'Calendar_Model_FreeBusy',
292                 'Calendar_Model_Exdate',
293                 'Calendar_Model_Attender',
294                 'Calendar_Model_AttendeeStatus',
295             ),
296             'CoreData' => array(
297                 'CoreData_Model_CoreData',
298             ),
299             'Courses' => array(
300                 'Courses_Model_Course',
301             ),
302             'Crm' => array(
303                 'Crm_Model_LeadType',
304                 'Crm_Model_LeadSource',
305                 'Crm_Model_LeadState',
306                 'Crm_Model_Lead',
307             ),
308             'ExampleApplication' => array(
309                 'ExampleApplication_Model_ExampleRecord',
310                 'ExampleApplication_Model_Status',
311             ),
312             'Expressomail' => array(
313                 'Expressomail_Model_Account',
314                 'Expressomail_Model_Sieve_Vacation',
315                 'Expressomail_Model_Sieve_Rule',
316                 'Expressomail_Model_PreparedMessagePart',
317                 'Expressomail_Model_Message',
318                 'Expressomail_Model_Folder',
319             ),
320             'Felamimail' => array(
321                 'Felamimail_Model_Account',
322                 'Felamimail_Model_Sieve_Vacation',
323                 'Felamimail_Model_Sieve_Rule',
324                 'Felamimail_Model_PreparedMessagePart',
325                 'Felamimail_Model_Message',
326                 'Felamimail_Model_Folder',
327             ),
328             'Filemanager' => array(
329                 'Filemanager_Model_Node',
330                 'Filemanager_Model_DownloadLink',
331             ),
332             'HumanResources' => array(
333                 'HumanResources_Model_ExtraFreeTime',
334                 'HumanResources_Model_Account',
335                 'HumanResources_Model_Employee',
336                 'HumanResources_Model_FreeTimeType',
337                 'HumanResources_Model_ExtraFreeTimeType',
338                 'HumanResources_Model_FreeTimeStatus',
339                 'HumanResources_Model_Contract',
340                 'HumanResources_Model_CostCenter',
341                 'HumanResources_Model_FreeDay',
342                 'HumanResources_Model_WorkingTime',
343                 'HumanResources_Model_FreeTime',
344             ),
345             'Inventory' => array(
346                 'Inventory_Model_Status',
347                 'Inventory_Model_InventoryItem',
348             ),
349             'Phone' => array(
350                 'Phone_Model_Call',
351                 'Phone_Model_MyPhone',
352             ),
353             'Projects' => array(
354                 'Projects_Model_Project',
355                 'Projects_Model_AttendeeRole',
356                 'Projects_Model_Status',
357             ),
358             'Sales' => array(
359                 'Sales_Model_Number',
360                 'Sales_Model_Config',
361                 'Sales_Model_PurchaseInvoice',
362                 'Sales_Model_Supplier',
363                 'Sales_Model_PaymentMethod',
364                 'Sales_Model_OrderConfirmation',
365                 'Sales_Model_Customer',
366                 'Sales_Model_Address',
367                 'Sales_Model_ProductCategory',
368                 'Sales_Model_InvoiceCleared',
369                 'Sales_Model_InvoiceType',
370                 'Sales_Model_Invoice',
371                 'Sales_Model_Contract',
372                 'Sales_Model_InvoicePosition',
373                 'Sales_Model_Division',
374                 'Sales_Model_ProductAggregate',
375                 'Sales_Model_Offer',
376                 'Sales_Model_CostCenter',
377                 'Sales_Model_Product',
378             ),
379             'SimpleFAQ' => array(
380                 'SimpleFAQ_Model_Faq',
381                 'SimpleFAQ_Model_Config',
382             ),
383             'Tasks' => array(
384                 'Tasks_Model_Task',
385                 'Tasks_Model_Priority',
386                 'Tasks_Model_Pagination',
387                 'Tasks_Model_Status',
388             ),
389             'Timetracker' => array(
390                 'Timetracker_Model_TimeaccountGrants',
391                 'Timetracker_Model_Timesheet',
392                 'Timetracker_Model_Timeaccount',
393             ),
394             'Tinebase' => array(
395                 'Tinebase_Model_AccessLog',
396                 'Tinebase_Model_ContainerContent',
397                 'Tinebase_Model_Application',
398                 'Tinebase_Model_Registration',
399                 'Tinebase_Model_Image',
400                 'Tinebase_Model_Tree_Node',
401                 'Tinebase_Model_Tree_FileObject',
402                 'Tinebase_Model_ModificationLog',
403                 'Tinebase_Model_Config',
404                 'Tinebase_Model_Group',
405                 'Tinebase_Model_State',
406                 'Tinebase_Model_CredentialCache',
407                 'Tinebase_Model_PersistentFilterGrant',
408                 'Tinebase_Model_AsyncJob',
409                 'Tinebase_Model_CustomField_Value',
410                 'Tinebase_Model_CustomField_Config',
411                 'Tinebase_Model_CustomField_Grant',
412                 'Tinebase_Model_Container',
413                 'Tinebase_Model_Tag',
414                 'Tinebase_Model_Relation',
415                 'Tinebase_Model_TagRight',
416                 'Tinebase_Model_NoteType',
417                 'Tinebase_Model_Alarm',
418                 'Tinebase_Model_FullTag',
419                 'Tinebase_Model_SAMGroup',
420                 'Tinebase_Model_EmailUser',
421                 'Tinebase_Model_Department',
422                 'Tinebase_Model_ImportException',
423                 'Tinebase_Model_User',
424                 'Tinebase_Model_Role',
425                 'Tinebase_Model_Note',
426                 'Tinebase_Model_RoleRight',
427                 'Tinebase_Model_Pagination',
428                 'Tinebase_Model_TempFile',
429                 'Tinebase_Model_ImportExportDefinition',
430                 'Tinebase_Model_OpenId_Association',
431                 'Tinebase_Model_OpenId_TrustedSite',
432                 'Tinebase_Model_FullUser',
433                 'Tinebase_Model_Import',
434                 'Tinebase_Model_UpdateMultipleException',
435                 'Tinebase_Model_SAMUser',
436                 'Tinebase_Model_Path',
437                 'Tinebase_Model_Preference',
438                 'Tinebase_Model_PersistentObserver',
439                 'Tinebase_Model_Grants',
440             ),
441         );
442
443         // remove bogus apps
444         $remove = array('Voipmanager', 'RequestTracker', 'Sipgate', 'Expressodriver');
445         foreach($remove as $r)
446         {
447             if (($key = array_search($r, $appNames)) !== false) {
448                 unset($appNames[$key]);
449             }
450         }
451
452         // check all expected models are there
453         foreach($expectedData as $appName => $expectedModels) {
454             if (array_search($appName, $appNames) !== false) {
455                 foreach ($expectedModels as $expectedModel) {
456                     $this->assertTrue(array_search($expectedModel, $models) !== false, 'did not find model: ' . $expectedModel);
457                 }
458             }
459         }
460
461         // if there is at least one model, remove the app
462         foreach($models as $model) {
463             list($appName) = explode('_', $model);
464             if (($key = array_search($appName, $appNames)) !== false) {
465                 unset($appNames[$key]);
466             }
467         }
468
469         // no apps should remain => we found models for each app, expect the bogus ones from above
470         $this->assertEquals(0, count($appNames), 'applications found for which no models where found: '.print_r($appNames, true));
471
472         // check if we found to much models
473         $appNames = $applications->name;
474         foreach($expectedData as $appName => $expectedModels) {
475             if (array_search($appName, $appNames) !== false) {
476                 foreach ($expectedModels as $expectedModel) {
477                     if (($key = array_search($expectedModel, $models)) !== false) {
478                         unset($models[$key]);
479                     }
480                 }
481             }
482         }
483
484         // no models should remain
485         $this->assertEquals(0, count($models), 'unexpected models found: '.print_r($models, true));
486     }
487 }