d78fec6f2823695cba0fe9e6a73c6c7cf5cdbf4f
[tine20] / tests / tine20 / TestCase.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * @package     Tests
6  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
7  * @copyright   Copyright (c) 2013-2015 Metaways Infosystems GmbH (http://www.metaways.de)
8  * @author      Philipp Schüle <p.schuele@metaways.de>
9  */
10
11 /**
12  * Test helper
13  */
14 require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestHelper.php';
15
16 /**
17  * Abstract test class
18  * 
19  * @package     Tests
20  */
21 abstract class TestCase extends PHPUnit_Framework_TestCase
22 {
23     /**
24      * transaction id if test is wrapped in an transaction
25      * 
26      * @var string
27      */
28     protected $_transactionId = null;
29     
30     /**
31      * usernames to be deleted (in sync backend)
32      * 
33      * @var array
34      */
35     protected $_usernamesToDelete = array();
36     
37     /**
38      * groups (ID) to be deleted (in sync backend)
39      * 
40      * @var array
41      */
42     protected $_groupIdsToDelete = array();
43     
44     /**
45      * remove group members, too when deleting groups
46      * 
47      * @var boolean
48      */
49     protected $_removeGroupMembers = true;
50     
51     /**
52      * invalidate roles cache
53      * 
54      * @var boolean
55      */
56     protected $_invalidateRolesCache = false;
57     
58     /**
59      * test personas
60      * 
61      * @var array
62      */
63     protected $_personas = array();
64     
65     /**
66      * unit in test
67      *
68      * @var Object
69      */
70     protected $_uit = null;
71     
72     /**
73      * the test user
74      *
75      * @var Tinebase_Model_FullUser
76      */
77     protected $_originalTestUser;
78     
79     /**
80      * the mailer
81      * 
82      * @var Zend_Mail_Transport_Abstract
83      */
84     protected static $_mailer = null;
85
86     /**
87      * db lock ids to be released
88      *
89      * @var array
90      */
91     protected $_releaseDBLockIds = array();
92
93     /**
94      * set up tests
95      */
96     protected function setUp()
97     {
98         $this->_transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
99         
100         Addressbook_Controller_Contact::getInstance()->setGeoDataForContacts(false);
101         
102         $this->_personas = Zend_Registry::get('personas');
103         
104         $this->_originalTestUser = Tinebase_Core::getUser();
105     }
106     
107     /**
108      * tear down tests
109      */
110     protected function tearDown()
111     {
112         if (in_array(Tinebase_User::getConfiguredBackend(), array(Tinebase_User::LDAP, Tinebase_User::ACTIVEDIRECTORY))) {
113             $this->_deleteUsers();
114             $this->_deleteGroups();
115         }
116         if ($this->_transactionId) {
117             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG))
118                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Rolling back test transaction');
119             Tinebase_TransactionManager::getInstance()->rollBack();
120         }
121         
122         Addressbook_Controller_Contact::getInstance()->setGeoDataForContacts(true);
123
124         if ($this->_originalTestUser instanceof Tinebase_Model_User) {
125             Tinebase_Core::set(Tinebase_Core::USER, $this->_originalTestUser);
126         }
127         
128         if ($this->_invalidateRolesCache) {
129             Tinebase_Acl_Roles::getInstance()->resetClassCache();
130         }
131
132         Tinebase_Cache_PerRequest::getInstance()->reset();
133
134         $this->_releaseDBLocks();
135     }
136
137     /**
138      * release db locks
139      */
140     protected function _releaseDBLocks()
141     {
142         foreach ($this->_releaseDBLockIds as $lockId) {
143             Tinebase_Lock::releaseDBSessionLock($lockId);
144         }
145
146         $this->_releaseDBLockIds = array();
147     }
148
149     /**
150      * tear down after test class
151      */
152     public static function tearDownAfterClass()
153     {
154         Tinebase_Core::getDbProfiling();
155     }
156     
157     /**
158      * test needs transaction
159      */
160     protected function _testNeedsTransaction()
161     {
162         if ($this->_transactionId) {
163             Tinebase_TransactionManager::getInstance()->commitTransaction($this->_transactionId);
164             $this->_transactionId = null;
165         }
166     }
167     
168     /**
169      * get tag
170      *
171      * @param string $tagType
172      * @param string $tagName
173      * @param array $contexts
174      * @return Tinebase_Model_Tag
175      */
176     protected function _getTag($tagType = Tinebase_Model_Tag::TYPE_SHARED, $tagName = NULL, $contexts = NULL)
177     {
178         if ($tagName) {
179             try {
180                 $tag = Tinebase_Tags::getInstance()->getTagByName($tagName);
181                 return $tag;
182             } catch (Tinebase_Exception_NotFound $tenf) {
183             }
184         } else {
185             $tagName = Tinebase_Record_Abstract::generateUID();
186         }
187     
188         $targ = array(
189             'type'          => $tagType,
190             'name'          => $tagName,
191             'description'   => 'testTagDescription',
192             'color'         => '#009B31',
193         );
194     
195         if ($contexts) {
196             $targ['contexts'] = $contexts;
197         }
198     
199         return new Tinebase_Model_Tag($targ);
200     }
201     
202     /**
203      * delete groups and their members
204      * 
205      * - also deletes groups and users in sync backends
206      */
207     protected function _deleteGroups()
208     {
209         if (! is_array($this->_groupIdsToDelete)) {
210             return;
211         }
212
213         foreach ($this->_groupIdsToDelete as $groupId) {
214             if ($this->_removeGroupMembers) {
215                 foreach (Tinebase_Group::getInstance()->getGroupMembers($groupId) as $userId) {
216                     try {
217                         Tinebase_User::getInstance()->deleteUser($userId);
218                     } catch (Exception $e) {
219                         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
220                             . ' error while deleting user: ' . $e->getMessage());
221                     }
222                 }
223             }
224             try {
225                 Tinebase_Group::getInstance()->deleteGroups($groupId);
226             } catch (Exception $e) {
227                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
228                     . ' error while deleting group: ' . $e->getMessage());
229             }
230         }
231     }
232     
233     /**
234      * delete users
235      */
236     protected function _deleteUsers()
237     {
238
239
240         foreach ($this->_usernamesToDelete as $username) {
241             try {
242                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
243                     . ' Trying to delete user: ' . $username);
244
245                 Tinebase_User::getInstance()->deleteUser(Tinebase_User::getInstance()->getUserByLoginName($username));
246             } catch (Exception $e) {
247                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
248                     . ' Error while deleting user: ' . $e->getMessage());
249             }
250         }
251     }
252
253     /**
254      * get personal container
255      * 
256      * @param string $applicationName
257      * @param Tinebase_Model_User $user
258      * @return Tinebase_Model_Container
259      */
260     protected function _getPersonalContainer($applicationName, $user = null)
261     {
262         if ($user === null) {
263             $user = Tinebase_Core::getUser();
264         }
265         
266         $personalContainer = Tinebase_Container::getInstance()->getPersonalContainer(
267             $user,
268             $applicationName, 
269             $user,
270             Tinebase_Model_Grants::GRANT_EDIT
271         )->getFirstRecord();
272
273         if (! $personalContainer) {
274             throw new Tinebase_Exception_UnexpectedValue('no personal container found!');
275         }
276
277         return $personalContainer;
278     }
279     
280     /**
281      * get test container
282      * 
283      * @param string $applicationName
284      * @param string $model
285      */
286     protected function _getTestContainer($applicationName, $model = null)
287     {
288         return Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
289             'name'           => 'PHPUnit ' . $model .' container',
290             'type'           => Tinebase_Model_Container::TYPE_PERSONAL,
291             'owner_id'       => Tinebase_Core::getUser(),
292             'backend'        => 'Sql',
293             'application_id' => Tinebase_Application::getInstance()->getApplicationByName($applicationName)->getId(),
294             'model'          => $model,
295         ), true));
296     }
297     
298     /**
299      * get test mail domain
300      * 
301      * @return string
302      */
303     protected function _getMailDomain()
304     {
305         return TestServer::getPrimaryMailDomain();
306     }
307     
308     /**
309      * get test user email address
310      * 
311      * @return test user email address
312      */
313     protected function _getEmailAddress()
314     {
315         $testConfig = Zend_Registry::get('testConfig');
316         return ($testConfig->email) ? $testConfig->email : Tinebase_Core::getUser()->accountEmailAddress;
317     }
318     
319     /**
320      * lazy init of uit
321      * 
322      * @return Object
323      * 
324      * @todo fix ide object class detection for completions
325      */
326     protected function _getUit()
327     {
328         if ($this->_uit === null) {
329             $uitClass = preg_replace('/Tests{0,1}$/', '', get_class($this));
330             if (@method_exists($uitClass, 'getInstance')) {
331                 $this->_uit = call_user_func($uitClass . '::getInstance');
332             } else if (@class_exists($uitClass)) {
333                 $this->_uit = new $uitClass();
334             } else {
335                 throw new Exception('could not find class ' . $uitClass);
336             }
337         }
338         
339         return $this->_uit;
340     }
341     
342     /**
343      * get messages
344      * 
345      * @return array
346      */
347     public static function getMessages()
348     {
349         // make sure messages are sent if queue is activated
350         if (isset(Tinebase_Core::getConfig()->actionqueue)) {
351             Tinebase_ActionQueue::getInstance()->processQueue(100);
352         }
353         
354         return self::getMailer()->getMessages();
355     }
356     
357     /**
358      * get mailer
359      * 
360      * @return Zend_Mail_Transport_Abstract
361      */
362     public static function getMailer()
363     {
364         if (! self::$_mailer) {
365             self::$_mailer = Tinebase_Smtp::getDefaultTransport();
366         }
367         
368         return self::$_mailer;
369     }
370     
371     /**
372      * flush mailer (send all remaining mails first)
373      */
374     public static function flushMailer()
375     {
376         // make sure all messages are sent if queue is activated
377         if (isset(Tinebase_Core::getConfig()->actionqueue)) {
378             Tinebase_ActionQueue::getInstance()->processQueue(10000);
379         }
380         
381         self::getMailer()->flush();
382     }
383     
384     /**
385      * returns the content.xml of an ods document
386      * 
387      * @param string $filename
388      * @return SimpleXMLElement
389      */
390     protected function _getContentXML($filename)
391     {
392         $zipHandler = zip_open($filename);
393         
394         do {
395             $entry = zip_read($zipHandler);
396         } while ($entry && zip_entry_name($entry) != "content.xml");
397         
398         // open entry
399         zip_entry_open($zipHandler, $entry, "r");
400         
401         // read entry
402         $entryContent = zip_entry_read($entry, zip_entry_filesize($entry));
403         
404         $xml = simplexml_load_string($entryContent);
405         zip_close($zipHandler);
406         
407         return $xml;
408     }
409     
410     /**
411      * get test temp file
412      * 
413      * @return Tinebase_TempFile
414      */
415     protected function _getTempFile()
416     {
417         $tempFileBackend = new Tinebase_TempFile();
418         $tempFile = $tempFileBackend->createTempFile(dirname(__FILE__) . '/Filemanager/files/test.txt');
419         return $tempFile;
420     }
421     
422     /**
423      * remove right in all users roles
424      * 
425      * @param string $applicationName
426      * @param string $right
427      * @param boolean $removeAdminRight
428      * @return array original role rights by role id
429      */
430     protected function _removeRoleRight($applicationName, $rightToRemove, $removeAdminRight = true)
431     {
432         $app = Tinebase_Application::getInstance()->getApplicationByName($applicationName);
433         $rolesOfUser = Tinebase_Acl_Roles::getInstance()->getRoleMemberships(Tinebase_Core::getUser()->getId());
434         $this->_invalidateRolesCache = true;
435
436         $roleRights = array();
437         foreach ($rolesOfUser as $roleId) {
438             $roleRights[$roleId] = $rights = Tinebase_Acl_Roles::getInstance()->getRoleRights($roleId);
439             foreach ($rights as $idx => $right) {
440                 if ($right['application_id'] === $app->getId() && ($right['right'] === $rightToRemove || $right['right'] === Tinebase_Acl_Rights_Abstract::ADMIN)) {
441                     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
442                         . ' Removing right ' . $right['right'] . ' from app ' . $applicationName . ' in role (id) ' . $roleId);
443                     unset($rights[$idx]);
444                 }
445             }
446             Tinebase_Acl_Roles::getInstance()->setRoleRights($roleId, $rights);
447         }
448         
449         return $roleRights;
450     }
451     
452     /**
453      * set grants for a persona and the current user
454      * 
455      * @param integer $containerId
456      * @param string $persona
457      * @param string $adminGrant
458      */
459     protected function _setPersonaGrantsForTestContainer($containerId, $persona, $personaAdminGrant = false, $userAdminGrant = true)
460     {
461         $grants = new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array(array(
462             'account_id'    => $this->_personas[$persona]->getId(),
463             'account_type'  => 'user',
464             Tinebase_Model_Grants::GRANT_READ     => true,
465             Tinebase_Model_Grants::GRANT_ADD      => true,
466             Tinebase_Model_Grants::GRANT_EDIT     => true,
467             Tinebase_Model_Grants::GRANT_DELETE   => true,
468             Tinebase_Model_Grants::GRANT_ADMIN    => $personaAdminGrant,
469         ), array(
470             'account_id'    => Tinebase_Core::getUser()->getId(),
471             'account_type'  => 'user',
472             Tinebase_Model_Grants::GRANT_READ     => true,
473             Tinebase_Model_Grants::GRANT_ADD      => true,
474             Tinebase_Model_Grants::GRANT_EDIT     => true,
475             Tinebase_Model_Grants::GRANT_DELETE   => true,
476             Tinebase_Model_Grants::GRANT_ADMIN    => $userAdminGrant,
477         )));
478         
479         Tinebase_Container::getInstance()->setGrants($containerId, $grants, TRUE);
480     }
481
482     /**
483      * set current user
484      *
485      * @param $user
486      * @throws Tinebase_Exception_InvalidArgument
487      */
488     protected function _setUser($user)
489     {
490         Tinebase_Core::set(Tinebase_Core::USER, $user);
491     }
492
493     /**
494      * call handle cli function with params
495      *
496      * @param array $_params
497      */
498     protected function _cliHelper($command, $_params)
499     {
500         $opts = new Zend_Console_Getopt(array($command => $command));
501         $opts->setArguments($_params);
502         ob_start();
503         $this->_cli->handle($opts, false);
504         $out = ob_get_clean();
505         return $out;
506     }
507
508     /**
509      * returns true if main db adapter is postgresql
510      *
511      * @return bool
512      */
513     protected function _dbIsPgsql()
514     {
515         $db = Tinebase_Core::getDb();
516         return ($db instanceof Zend_Db_Adapter_Pdo_Pgsql);
517     }
518 }