1<?php 2 3/** 4 * mysql tests for the authpdo plugin 5 * 6 * @group plugin_authpdo 7 * @group plugins 8 */ 9class mysql_plugin_authpdo_test extends DokuWikiTest { 10 11 protected $driver = 'mysql'; 12 protected $host = ''; 13 protected $database = 'authpdo_testing'; 14 protected $user = ''; 15 protected $pass = ''; 16 protected $port = ''; 17 18 public function setUp() { 19 parent::setUp(); 20 $configuration = DOKU_UNITTEST . "{$this->driver}.conf.php"; 21 if(!file_exists($configuration)) { 22 return; 23 } 24 /** @var $conf array */ 25 include $configuration; 26 $this->host = $conf['host']; 27 $this->user = $conf['user']; 28 $this->pass = $conf['pass']; 29 $this->port = $conf['port']; 30 } 31 32 /** 33 * try to remove the last set up database 34 * 35 * it might still be there if something went wrong 36 */ 37 public function tearDown() { 38 parent::tearDown(); 39 $this->dropDatabase(); 40 } 41 42 /** 43 * Check if database credentials and extensions exist 44 */ 45 public function test_requirements() { 46 if(!$this->host || !$this->user) { 47 $this->markTestSkipped("Skipped {$this->driver} tests. Missing configuration"); 48 } 49 if(!class_exists('PDO')) { 50 $this->markTestSkipped("Skipped {$this->driver} tests. Missing PDO extension"); 51 } 52 if(!in_array($this->driver, pdo_drivers())) { 53 $this->markTestSkipped("Skipped {$this->driver} tests. Missing pdo_{$this->driver} extension"); 54 } 55 } 56 57 /** 58 * create the database for testing 59 */ 60 protected function createDatabase() { 61 $pdo = new PDO( 62 "{$this->driver}:host={$this->host};port={$this->port}", $this->user, $this->pass, 63 array( 64 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes 65 ) 66 ); 67 $pdo->exec("DROP DATABASE IF EXISTS {$this->database}"); 68 $pdo->exec("CREATE DATABASE {$this->database}"); 69 $pdo = null; 70 } 71 72 /** 73 * remove the database 74 */ 75 protected function dropDatabase() { 76 $pdo = new PDO( 77 "{$this->driver}:host={$this->host};port={$this->port}", $this->user, $this->pass, 78 array( 79 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes 80 ) 81 ); 82 try { 83 $pdo->exec("DROP DATABASE IF EXISTS {$this->database}"); 84 } catch (PDOException $e) { 85 // ignore - sometimes this fails even though the database was deleted 86 } 87 $pdo = null; 88 } 89 90 /** 91 * imports a database dump 92 * 93 * @param $file 94 */ 95 protected function importDatabase($file) { 96 // connect to database and import dump 97 $pdo = null; 98 $pdo = new PDO( 99 "{$this->driver}:dbname={$this->database};host={$this->host};port={$this->port}", $this->user, $this->pass, 100 array( 101 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes 102 ) 103 ); 104 $sql = file_get_contents($file); 105 $pdo->exec($sql); 106 $pdo = null; 107 } 108 109 /** 110 * Run general tests on all users 111 * 112 * @param auth_plugin_authpdo $auth 113 * @param array $users 114 */ 115 protected function runGeneralTests(auth_plugin_authpdo $auth, $users) { 116 global $conf; 117 $info = 'DSN: ' . $auth->getConf('dsn'); 118 $this->assertTrue($auth->success, $info); 119 120 if($auth->canDo('getUsers')) { 121 $list = $auth->retrieveUsers(); 122 $this->assertGreaterThanOrEqual(count($users), count($list), $info); 123 } 124 125 if($auth->canDo('getGroups')) { 126 $list = $auth->retrieveGroups(); 127 $this->assertGreaterThanOrEqual(1, $list, $info); 128 } 129 130 if($auth->canDo('getUserCount')) { 131 $count = $auth->getUserCount(); 132 $this->assertGreaterThanOrEqual(count($users), $count); 133 } 134 135 if($auth->canDo('addUser')) { 136 $newuser = array( 137 'user' => 'newuserfoobar', 138 'name' => 'First LastFoobar', 139 'pass' => 'password', 140 'mail' => 'newuserfoobar@example.com', 141 'grps' => array('acompletelynewgroup') 142 ); 143 $ok = $auth->createUser( 144 $newuser['user'], 145 $newuser['pass'], 146 $newuser['name'], 147 $newuser['mail'], 148 $newuser['grps'] 149 ); 150 $this->assertTrue($ok, $info); 151 $check = $auth->getUserData($newuser['user']); 152 $this->assertEquals($newuser['user'], $check['user'], $info); 153 $this->assertEquals($newuser['mail'], $check['mail'], $info); 154 $groups = array_merge($newuser['grps'], array($conf['defaultgroup'])); 155 $this->assertEquals($groups, $check['grps'], $info); 156 } 157 } 158 159 /** 160 * run all the tests with the given user, depending on the capabilities 161 * 162 * @param auth_plugin_authpdo $auth 163 * @param $user 164 */ 165 protected function runUserTests(auth_plugin_authpdo $auth, $user) { 166 global $conf; 167 $info = 'DSN: ' . $auth->getConf('dsn') . ' User:' . $user['user']; 168 169 // minimal setup 170 $this->assertTrue($auth->checkPass($user['user'], $user['pass']), $info); 171 $check = $auth->getUserData($user['user']); 172 $this->assertEquals($user['user'], $check['user'], $info); 173 $this->assertEquals($user['name'], $check['name'], $info); 174 $this->assertEquals($user['mail'], $check['mail'], $info); 175 $groups = array_merge($user['grps'], array($conf['defaultgroup'])); 176 $this->assertEquals($groups, $check['grps'], $info); 177 178 // getUsers 179 if($auth->canDo('getUsers')) { 180 $list = $auth->retrieveUsers(0, -1, array('user' => $user['user'])); 181 $this->assertGreaterThanOrEqual(1, count($list)); 182 $list = $auth->retrieveUsers(0, -1, array('name' => $user['name'])); 183 $this->assertGreaterThanOrEqual(1, count($list)); 184 $list = $auth->retrieveUsers(0, -1, array('mail' => $user['mail'])); 185 $this->assertGreaterThanOrEqual(1, count($list)); 186 } 187 188 // getUserCount 189 if($auth->canDo('getUserCount')) { 190 $count = $auth->getUserCount(array('user' => $user['user'])); 191 $this->assertGreaterThanOrEqual(1, $count); 192 $count = $auth->getUserCount(array('name' => $user['name'])); 193 $this->assertGreaterThanOrEqual(1, $count); 194 $count = $auth->getUserCount(array('mail' => $user['mail'])); 195 $this->assertGreaterThanOrEqual(1, $count); 196 } 197 198 // modGroups 199 if($auth->canDo('modGroups')) { 200 $newgroup = 'foobar'; 201 $ok = $auth->modifyUser($user['user'], array('grps' => array($newgroup))); 202 $this->assertTrue($ok, $info); 203 $check = $auth->getUserData($user['user']); 204 $this->assertTrue(in_array($newgroup, $check['grps']), $info); 205 } 206 207 // modPass 208 if($auth->canDo('modPass')) { 209 $newpass = 'foobar'; 210 $ok = $auth->modifyUser($user['user'], array('pass' => $newpass)); 211 $this->assertTrue($ok, $info); 212 $this->assertTrue($auth->checkPass($user['user'], $newpass), $info); 213 } 214 215 // modMail 216 if($auth->canDo('modMail')) { 217 $newmail = 'foobar@example.com'; 218 $ok = $auth->modifyUser($user['user'], array('mail' => $newmail)); 219 $this->assertTrue($ok, $info); 220 $check = $auth->getUserData($user['user']); 221 $this->assertEquals($newmail, $check['mail'], $info); 222 } 223 224 // modName 225 if($auth->canDo('modName')) { 226 $newname = 'FirstName Foobar'; 227 $ok = $auth->modifyUser($user['user'], array('name' => $newname)); 228 $this->assertTrue($ok, $info); 229 $check = $auth->getUserData($user['user']); 230 $this->assertEquals($newname, $check['name'], $info); 231 } 232 233 // modLogin 234 if($auth->canDo('modLogin')) { 235 $newuser = 'foobar' . $user['user']; 236 $ok = $auth->modifyUser($user['user'], array('user' => $newuser)); 237 $this->assertTrue($ok, $info); 238 $check = $auth->getUserData($newuser); 239 $this->assertEquals($newuser, $check['user'], $info); 240 // rename back 241 $ok = $auth->modifyUser($newuser, array('user' => $user['user'])); 242 $this->assertTrue($ok, $info); 243 } 244 245 // delUser 246 if($auth->canDo('delUser')) { 247 $num = $auth->deleteUsers(array($user['user'])); 248 $this->assertEquals(1, $num, $info); 249 $this->assertFalse($auth->getUserData($user['user']), $info); 250 } 251 } 252 253 /** 254 * prepares the individual configurations for testing 255 * 256 * @return array 257 */ 258 public function data_provider() { 259 $testdata = array(); 260 261 $files = glob(__DIR__ . "/{$this->driver}/*.php"); 262 foreach($files as $file) { 263 $dump = preg_replace('/\.php$/', '.sql', $file); 264 $dbname = 'authpdo_testing_' . basename($file, '.php'); 265 266 /** @var $data array */ 267 include $file; 268 269 $testdata[] = array($dbname, $dump, $data); 270 } 271 272 return $testdata; 273 } 274 275 /** 276 * This triggers all the tests based on the dumps and configurations 277 * 278 * @dataProvider data_provider 279 * @depends test_requirements 280 * @param string $dbname Name of the database to use 281 * @param string $dump The path to the dump file to import 282 * @param array|string $data config and test user setup. When a string is passed, test is skipped with that msg 283 */ 284 public function test_database($dbname, $dump, $data){ 285 global $conf; 286 287 if(!is_array($data)) { 288 $this->markTestSkipped($data); 289 return; 290 } 291 292 $this->database = $dbname; 293 294 $this->createDatabase(); 295 $this->importDatabase($dump); 296 297 // Setup the configuration and initialize a new auth object 298 $conf['plugin']['authpdo'] = array(); 299 $conf['plugin']['authpdo'] = $data['conf']; 300 $conf['plugin']['authpdo']['dsn'] = "{$this->driver}:dbname={$this->database};host={$this->host};port={$this->port}"; 301 $conf['plugin']['authpdo']['user'] = $this->user; 302 $conf['plugin']['authpdo']['pass'] = $this->pass; 303 $conf['plugin']['authpdo']['debug'] = 1; 304 if($data['passcrypt']) $conf['passcrypt'] = $data['passcrypt']; 305 $auth = new auth_plugin_authpdo(); 306 307 $this->runGeneralTests($auth, $data['users']); 308 foreach($data['users'] as $user) { 309 $this->runUserTests($auth, $user); 310 } 311 312 $this->dropDatabase(); 313 } 314 315} 316