xref: /dokuwiki/lib/plugins/authpdo/_test/mysql.test.php (revision 920904359a7088e3cf3885a96c03c453aa9e4095)
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