Merge branch '2014.11-develop' into 2015.11
[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 (Tinebase_User::getConfiguredBackend() === Tinebase_User::LDAP) {
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         foreach ($this->_groupIdsToDelete as $groupId) {
210             if ($this->_removeGroupMembers) {
211                 foreach (Tinebase_Group::getInstance()->getGroupMembers($groupId) as $userId) {
212                     try {
213                         Tinebase_User::getInstance()->deleteUser($userId);
214                     } catch (Exception $e) {
215                         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
216                             . ' error while deleting user: ' . $e->getMessage());
217                     }
218                 }
219             }
220             try {
221                 Tinebase_Group::getInstance()->deleteGroups($groupId);
222             } catch (Exception $e) {
223                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
224                     . ' error while deleting group: ' . $e->getMessage());
225             }
226         }
227     }
228     
229     /**
230      * delete users
231      */
232     protected function _deleteUsers()
233     {
234
235
236         foreach ($this->_usernamesToDelete as $username) {
237             try {
238                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
239                     . ' Trying to delete user: ' . $username);
240
241                 Tinebase_User::getInstance()->deleteUser(Tinebase_User::getInstance()->getUserByLoginName($username));
242             } catch (Exception $e) {
243                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
244                     . ' Error while deleting user: ' . $e->getMessage());
245             }
246         }
247     }
248
249     /**
250      * get personal container
251      * 
252      * @param string $applicationName
253      * @param Tinebase_Model_User $user
254      * @return Tinebase_Model_Container
255      */
256     protected function _getPersonalContainer($applicationName, $user = null)
257     {
258         if ($user === null) {
259             $user = Tinebase_Core::getUser();
260         }
261         
262         $personalContainer = Tinebase_Container::getInstance()->getPersonalContainer(
263             $user,
264             $applicationName, 
265             $user,
266             Tinebase_Model_Grants::GRANT_EDIT
267         )->getFirstRecord();
268
269         if (! $personalContainer) {
270             throw new Tinebase_Exception_UnexpectedValue('no personal container found!');
271         }
272
273         return $personalContainer;
274     }
275     
276     /**
277      * get test container
278      * 
279      * @param string $applicationName
280      * @param string $model
281      */
282     protected function _getTestContainer($applicationName, $model = null)
283     {
284         return Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
285             'name'           => 'PHPUnit ' . $model .' container',
286             'type'           => Tinebase_Model_Container::TYPE_PERSONAL,
287             'owner_id'       => Tinebase_Core::getUser(),
288             'backend'        => 'Sql',
289             'application_id' => Tinebase_Application::getInstance()->getApplicationByName($applicationName)->getId(),
290             'model'          => $model,
291         ), true));
292     }
293     
294     /**
295      * get test mail domain
296      * 
297      * @return string
298      */
299     protected function _getMailDomain()
300     {
301         $testconfig = Zend_Registry::get('testConfig');
302         
303         if ($testconfig && isset($testconfig->maildomain)) {
304             return $testconfig->maildomain;
305         }
306         
307         if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
308             list($user, $domain) = explode('@', Tinebase_Core::getUser()->accountEmailAddress, 2);
309             
310             return $domain;
311         }
312         
313         return 'tine20.org';
314     }
315     
316     /**
317      * get test user email address
318      * 
319      * @return test user email address
320      */
321     protected function _getEmailAddress()
322     {
323         $testConfig = Zend_Registry::get('testConfig');
324         return ($testConfig->email) ? $testConfig->email : Tinebase_Core::getUser()->accountEmailAddress;
325     }
326     
327     /**
328      * lazy init of uit
329      * 
330      * @return Object
331      * 
332      * @todo fix ide object class detection for completions
333      */
334     protected function _getUit()
335     {
336         if ($this->_uit === null) {
337             $uitClass = preg_replace('/Tests{0,1}$/', '', get_class($this));
338             if (@method_exists($uitClass, 'getInstance')) {
339                 $this->_uit = call_user_func($uitClass . '::getInstance');
340             } else if (@class_exists($uitClass)) {
341                 $this->_uit = new $uitClass();
342             } else {
343                 throw new Exception('could not find class ' . $uitClass);
344             }
345         }
346         
347         return $this->_uit;
348     }
349     
350     /**
351      * get messages
352      * 
353      * @return array
354      */
355     public static function getMessages()
356     {
357         // make sure messages are sent if queue is activated
358         if (isset(Tinebase_Core::getConfig()->actionqueue)) {
359             Tinebase_ActionQueue::getInstance()->processQueue(100);
360         }
361         
362         return self::getMailer()->getMessages();
363     }
364     
365     /**
366      * get mailer
367      * 
368      * @return Zend_Mail_Transport_Abstract
369      */
370     public static function getMailer()
371     {
372         if (! self::$_mailer) {
373             self::$_mailer = Tinebase_Smtp::getDefaultTransport();
374         }
375         
376         return self::$_mailer;
377     }
378     
379     /**
380      * flush mailer (send all remaining mails first)
381      */
382     public static function flushMailer()
383     {
384         // make sure all messages are sent if queue is activated
385         if (isset(Tinebase_Core::getConfig()->actionqueue)) {
386             Tinebase_ActionQueue::getInstance()->processQueue(10000);
387         }
388         
389         self::getMailer()->flush();
390     }
391     
392     /**
393      * returns the content.xml of an ods document
394      * 
395      * @param string $filename
396      * @return SimpleXMLElement
397      */
398     protected function _getContentXML($filename)
399     {
400         $zipHandler = zip_open($filename);
401         
402         do {
403             $entry = zip_read($zipHandler);
404         } while ($entry && zip_entry_name($entry) != "content.xml");
405         
406         // open entry
407         zip_entry_open($zipHandler, $entry, "r");
408         
409         // read entry
410         $entryContent = zip_entry_read($entry, zip_entry_filesize($entry));
411         
412         $xml = simplexml_load_string($entryContent);
413         zip_close($zipHandler);
414         
415         return $xml;
416     }
417     
418     /**
419      * get test temp file
420      * 
421      * @return Tinebase_TempFile
422      */
423     protected function _getTempFile()
424     {
425         $tempFileBackend = new Tinebase_TempFile();
426         $tempFile = $tempFileBackend->createTempFile(dirname(__FILE__) . '/Filemanager/files/test.txt');
427         return $tempFile;
428     }
429     
430     /**
431      * remove right in all users roles
432      * 
433      * @param string $applicationName
434      * @param string $right
435      * @param boolean $removeAdminRight
436      * @return array original role rights by role id
437      */
438     protected function _removeRoleRight($applicationName, $rightToRemove, $removeAdminRight = true)
439     {
440         $app = Tinebase_Application::getInstance()->getApplicationByName($applicationName);
441         $rolesOfUser = Tinebase_Acl_Roles::getInstance()->getRoleMemberships(Tinebase_Core::getUser()->getId());
442         $this->_invalidateRolesCache = true;
443
444         $roleRights = array();
445         foreach ($rolesOfUser as $roleId) {
446             $roleRights[$roleId] = $rights = Tinebase_Acl_Roles::getInstance()->getRoleRights($roleId);
447             foreach ($rights as $idx => $right) {
448                 if ($right['application_id'] === $app->getId() && ($right['right'] === $rightToRemove || $right['right'] === Tinebase_Acl_Rights_Abstract::ADMIN)) {
449                     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
450                         . ' Removing right ' . $right['right'] . ' from app ' . $applicationName . ' in role (id) ' . $roleId);
451                     unset($rights[$idx]);
452                 }
453             }
454             Tinebase_Acl_Roles::getInstance()->setRoleRights($roleId, $rights);
455         }
456         
457         return $roleRights;
458     }
459     
460     /**
461      * set grants for a persona and the current user
462      * 
463      * @param integer $containerId
464      * @param string $persona
465      * @param string $adminGrant
466      */
467     protected function _setPersonaGrantsForTestContainer($containerId, $persona, $personaAdminGrant = false, $userAdminGrant = true)
468     {
469         $grants = new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array(array(
470             'account_id'    => $this->_personas[$persona]->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    => $personaAdminGrant,
477         ), array(
478             'account_id'    => Tinebase_Core::getUser()->getId(),
479             'account_type'  => 'user',
480             Tinebase_Model_Grants::GRANT_READ     => true,
481             Tinebase_Model_Grants::GRANT_ADD      => true,
482             Tinebase_Model_Grants::GRANT_EDIT     => true,
483             Tinebase_Model_Grants::GRANT_DELETE   => true,
484             Tinebase_Model_Grants::GRANT_ADMIN    => $userAdminGrant,
485         )));
486         
487         Tinebase_Container::getInstance()->setGrants($containerId, $grants, TRUE);
488     }
489
490     /**
491      * set current user
492      *
493      * @param $user
494      * @throws Tinebase_Exception_InvalidArgument
495      */
496     protected function _setUser($user)
497     {
498         Tinebase_Core::set(Tinebase_Core::USER, $user);
499     }
500 }