fix modlog test undo
[tine20] / tests / tine20 / TestServer.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     tests
6  * @subpackage  test root
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
8  * @copyright   Copyright (c) 2008-2013 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Cornelius Weiss <c.weiss@metaways.de>
10  * 
11  * @todo invent common bootstrap for ServerTests and normal Tests to avoid code duplication
12  */
13
14 /**
15  * helper class
16  */
17 class TestServer
18 {
19     /**
20      * holdes the instance of the singleton
21      *
22      * @var TestServer
23      */
24     private static $instance = NULL;
25
26     /**
27      * the constructor
28      *
29      */
30     public function __construct()
31     {
32     }
33
34     /**
35      * the singleton pattern
36      *
37      * @return TestServer
38      */
39     public static function getInstance()
40     {
41         if (self::$instance === NULL) {
42             self::$instance = new TestServer;
43         }
44
45         return self::$instance;
46     }
47
48     /**
49      * init the test framework
50      */
51     public function initFramework()
52     {
53         $this->setWhiteAndBlacklists();
54
55         $config = $this->getConfig();
56
57         // set some server vars. sabredav complains if REQUEST_URI is not set
58         $_SERVER['DOCUMENT_ROOT'] = $config->docroot;
59         $_SERVER['REQUEST_URI'] = '';
60
61         Tinebase_Core::startCoreSession();
62         
63         Tinebase_Core::initFramework();
64
65         // set default test mailer
66         Tinebase_Smtp::setDefaultTransport(new Zend_Mail_Transport_Array());
67
68         // set max execution time
69         Tinebase_Core::setExecutionLifeTime(1200);
70
71         if ($config->locale) {
72             Tinebase_Core::setupUserLocale($config->locale);
73         }
74         
75         // this is needed for session handling in unittests (deactivate Zend_Session::writeClose and others)
76         Zend_Session::$_unitTestEnabled = TRUE;
77
78         Tinebase_Core::set('frameworkInitialized', true);
79     }
80     
81     /**
82      * Set white / black lists
83      */
84     public function setWhiteAndBlacklists()
85     {
86         if ($this->isPhpunitVersionGreaterOrEquals("3.6.0")) {
87             // TODO not sure if this is working - we need to validate that
88             $filter = new PHP_CodeCoverage_Filter();
89             $filter->addDirectoryToBlacklist(PATH_TO_TEST_DIR);
90             $filter->addDirectoryToBlacklist(PATH_TO_TINE_LIBRARY);
91             $filter->addDirectoryToBlacklist(PATH_TO_REAL_DIR.'/Setup');
92             $filter->addDirectoryToBlacklist(PATH_TO_REAL_DIR.'/Zend');
93             $filter->addDirectoryToBlacklist(PATH_TO_REAL_DIR.'/vendor');
94         } else if ($this->isPhpunitVersionGreaterOrEquals("3.5.0")) {
95             PHP_CodeCoverage_Filter::getInstance()->addDirectoryToBlacklist(PATH_TO_TEST_DIR);
96             PHP_CodeCoverage_Filter::getInstance()->addDirectoryToBlacklist(PATH_TO_TINE_LIBRARY);
97             PHP_CodeCoverage_Filter::getInstance()->addDirectoryToBlacklist(PATH_TO_REAL_DIR.'/Setup');
98             PHP_CodeCoverage_Filter::getInstance()->addDirectoryToBlacklist(PATH_TO_REAL_DIR.'/Zend');
99         } else {
100             PHPUnit_Util_Filter::addDirectoryToFilter(PATH_TO_TEST_DIR);
101             PHPUnit_Util_Filter::addDirectoryToFilter(PATH_TO_TINE_LIBRARY);
102             PHPUnit_Util_Filter::addDirectoryToFilter(PATH_TO_REAL_DIR.'/Setup');
103             PHPUnit_Util_Filter::addDirectoryToFilter(PATH_TO_REAL_DIR.'/Zend');
104         }
105     }
106
107     /**
108      * inits (adds) some test users
109      */
110     public function initTestUsers()
111     {
112         $personas = $this->_getPersonas();
113         if (count($personas) !== 5) {
114             Addressbook_Controller_Contact::getInstance()->setGeoDataForContacts(false);
115             Admin_Setup_DemoData::getInstance()->createDemoData(array('en'));
116             Addressbook_Controller_Contact::getInstance()->setGeoDataForContacts(true);
117             $personas = $this->_getPersonas();
118         }
119         
120         Zend_Registry::set('personas', $personas);
121     }
122     
123     /**
124      * fetch persona user accounts
125      * 
126      * @return array loginname => useraccount
127      */
128     protected function _getPersonas()
129     {
130         $personas = array();
131         $personaLoginNames = array('sclever', 'rwright', 'pwulf', 'jmcblack', 'jsmith');
132         foreach ($personaLoginNames as $loginName) {
133             try {
134                 $personas[$loginName] = Tinebase_User::getInstance()->getFullUserByLoginName($loginName);
135             } catch (Tinebase_Exception_NotFound $tenf) {
136             }
137         }
138         return $personas;
139     }
140
141     /**
142      * set test user email address if in config
143      */
144     public function setTestUserEmail()
145     {
146         if ($this->getConfig()->email) {
147             // set email of test user contact
148             $testUserContact = Addressbook_Controller_Contact::getInstance()->getContactByUserId(Tinebase_Core::getUser()->getId());
149             $testUserContact->email = $this->getConfig()->email;
150             Addressbook_Controller_Contact::getInstance()->update($testUserContact, FALSE);
151         }
152     }
153
154     /**
155      * get test config
156      * 
157      * @return Zend_Config
158      */
159     public function getConfig()
160     {
161         if (! Zend_Registry::isRegistered('testConfig')) {
162             // get config
163             $configData = @include('phpunitconfig.inc.php');
164             if ($configData === false) {
165                 $configData = include('config.inc.php');
166             }
167             if ($configData === false) {
168                 die ('central configuration file config.inc.php not found in includepath: ' . get_include_path());
169             }
170             $config = new Zend_Config($configData);
171
172             Zend_Registry::set('testConfig', $config);
173         } else {
174             $config = Zend_Registry::get('testConfig');
175         }
176
177         return $config;
178     }
179     
180     /**
181      * assemble CLI command line call (tine20.php)
182      * 
183      * @param string $command
184      * @param bool   $addCredentials
185      * @return string
186      */
187     public static function assembleCliCommand($command = "", $addCredentials = FALSE)
188     {
189         //$backtrace = debug_backtrace();
190         //return $backtrace[1]['class'];
191  
192         $cmd = implode(' ', $_SERVER['argv']);
193         
194         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Original commmand: ' . $cmd);
195         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Script name: ' . $_SERVER['SCRIPT_NAME']);
196         
197         $cmd = preg_replace(array(
198             '@' . preg_quote($_SERVER['SCRIPT_NAME']) . '@',
199             '/--stderr /',
200             '/--colors{0,1} /',
201             '/--verbose /',
202             '/--stop-on-failure /',
203             '/[\S]+\.php$/',
204             '/ \S+Tests{0,1}/',
205             '/--debug\s*/',
206             '/--filter [\S]+\D/',
207             '/--configuration [\S]+\D/',
208             '/--exclude-group [\S]+\D/',
209             '/--coverage-[\S]+ [\S]+\D/',
210             '/-c [\S]+\D/',
211             '/--log-junit [\S]+\D/'
212         ), array(
213             'php',
214             '',
215             '',
216             '',
217             '',
218             '',
219             '',
220             '',
221             '',
222             '',
223             '',
224             '',
225             '',
226         ), $cmd);
227         
228         $cmd .= $command;
229         
230         if ($addCredentials) {
231             $credentials = TestServer::getInstance()->getTestCredentials();
232             $cmd .= " --username {$credentials['username']} --password {$credentials['password']}";
233         }
234         
235         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Assembled commmand: ' . $cmd);
236         
237         return $cmd;
238     }
239
240     /**
241      * replace maildomain in input file
242      * 
243      * @param string $filename
244      * @return string filename
245      */
246     public static function replaceEmailDomainInFile($filename)
247     {
248         $maildomain = self::getPrimaryMailDomain();
249         $tempPath = Tinebase_TempFile::getTempPath();
250         $contents = file_get_contents($filename);
251         $contents = preg_replace('/tine20.org/', $maildomain, $contents);
252         file_put_contents($tempPath, $contents);
253         
254         return $tempPath;
255     }
256
257     /**
258      * returns configured primary mail domain
259      *
260      * phpunit.config.inc > smtp config primary domain > current user mail domain > tine20.org
261      *
262      * @return mixed|string
263      */
264     public static function getPrimaryMailDomain()
265     {
266         $config = TestServer::getInstance()->getConfig();
267         if ($config->maildomain) {
268             return $config->maildomain;
269         } else {
270             $smtpConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::SMTP, new Tinebase_Config_Struct())->toArray();
271             if (isset($smtpConfig['primarydomain'])) {
272                 return $smtpConfig['primarydomain'];
273             }
274
275             if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
276                 list($user, $domain) = explode('@', Tinebase_Core::getUser()->accountEmailAddress, 2);
277                 return $domain;
278             }
279
280         }
281
282         return 'tine20.org';
283     }
284
285     /**
286      * isPhpunitVersionGreaterOrEquals
287      * 
288      * @param String $version for example '3.6.0'
289      */
290     public function isPhpunitVersionGreaterOrEquals($version)
291     {
292         $phpUnitVersion = explode(' ',PHPUnit_Runner_Version::getVersionString());
293         return (version_compare($phpUnitVersion[1], $version) >= 0);
294     }
295
296     /**
297      * login user
298      *
299      * @throws Exception
300      */
301     public function login()
302     {
303         $tinebaseController = Tinebase_Controller::getInstance();
304         $credentials = $this->getTestCredentials();
305         
306         $config = $this->getConfig();
307         $_SERVER['REMOTE_ADDR']     = $config->ip ? $config->ip : '127.0.0.1';
308         $_SERVER['HTTP_USER_AGENT'] = 'Unit Test Client';
309         if (! $tinebaseController->login($credentials['username'], $credentials['password'], new \Zend\Http\PhpEnvironment\Request(), 'TineUnittest')){
310             throw new Exception("Couldn't login, user session required for tests! \n");
311         }
312     }
313     
314     /**
315      * fetch test user credentials
316      * 
317      * @return array
318      * 
319      * @todo DRY: should be moved to abstract TestCase and used in ServerTestCase
320      */
321     public function getTestCredentials()
322     {
323         $config = $this->getConfig();
324         $username = isset($config->login->username) ? $config->login->username : $config->username;
325         $password = isset($config->login->password) ? $config->login->password : $config->password;
326         
327         return array(
328             'username' => $username,
329             'password' => $password
330         );
331     }
332 }