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