1<?php
2
3/**
4 * @group plugin_usermanager
5 * @group admin_plugins
6 * @group plugins
7 * @group bundled_plugins
8 */
9
10require_once(dirname(__FILE__).'/mocks.class.php');
11
12/**
13 *  !!!!! NOTE !!!!!
14 *
15 *  At present, users imported in individual tests remain in the user list for subsequent tests
16 */
17class plugin_usermanager_csv_import_test extends DokuWikiTest
18{
19    private $old_files;
20    protected $usermanager;
21    protected $importfile;
22
23    public function setUp() : void
24    {
25        $this->importfile = tempnam(TMP_DIR, 'csv');
26
27        $this->old_files = $_FILES;
28        $_FILES = array(
29            'import'    =>  array(
30                'name'      =>  'import.csv',
31                'tmp_name'  =>  $this->importfile,
32                'type'      =>  'text/plain',
33                'size'      =>  1,
34                'error'     =>  0,
35            ),
36        );
37
38        $this->usermanager = new admin_mock_usermanager();
39        parent::setUp();
40    }
41
42    public function tearDown() : void
43    {
44        $_FILES = $this->old_files;
45        parent::tearDown();
46    }
47
48    public function doImportTest($importCsv, $expectedResult, $expectedNewUsers, $expectedFailures)
49    {
50        global $auth;
51        $before_users = $auth->retrieveUsers();
52
53        io_saveFile($this->importfile, $importCsv);
54        $result = $this->usermanager->tryImport();
55
56        $after_users = $auth->retrieveUsers();
57
58        $before_users = array_map('serialize', $before_users);
59        $after_users = array_map('serialize', $after_users);
60        $import_count = count($after_users) - count($before_users);
61        $new_users = array_map('unserialize', array_diff_key($after_users, $before_users));
62        $diff_users = array_map('unserialize', array_diff_assoc($after_users, $before_users));
63
64        $expectedCount = count($expectedNewUsers);
65
66        $this->assertEquals($expectedResult, $result);                                       // import result as expected
67        $this->assertEquals($expectedCount, $import_count);                                  // number of new users matches expected number imported
68        $this->assertEquals($expectedNewUsers, $this->stripPasswords($new_users));           // new user data matches imported user data
69        $this->assertEquals($expectedCount, $this->countPasswords($new_users));              // new users have a password
70        $this->assertEquals($expectedCount, $this->usermanager->mock_email_notifications_sent);   // new users notified of their passwords
71        $this->assertEquals($new_users, $diff_users);                                        // no other users were harmed in the testing of this import
72        $this->assertEquals($expectedFailures, $this->usermanager->getImportFailures());     // failures as expected
73    }
74
75    public function test_cantImport()
76    {
77        global $auth;
78        $oldauth = $auth;
79
80        $auth = new auth_mock_authplain();
81        $auth->setCanDo('addUser', false);
82
83        $csv = 'User,"Real Name",Email,Groups
84importuser,"Ford Prefect",ford@example.com,user
85';
86
87        $this->doImportTest($csv, false, array(), array());
88
89        $auth = $oldauth;
90    }
91
92    public function test_import()
93    {
94        $csv = 'User,"Real Name",Email,Groups
95importuser,"Ford Prefect",ford@example.com,user
96';
97        $expected = array(
98            'importuser' => array(
99                'name'  => 'Ford Prefect',
100                'mail'  => 'ford@example.com',
101                'grps'  => array('user'),
102            ),
103        );
104
105        $this->doImportTest($csv, true, $expected, array());
106    }
107
108    public function test_importExisting()
109    {
110        $csv = 'User,"Real Name",Email,Groups
111importuser,"Ford Prefect",ford@example.com,user
112';
113        $failures = array(
114            '2' => array(
115                'error' => $this->usermanager->getLang('import_error_create'),
116                'user'  => array(
117                    'importuser',
118                    'Ford Prefect',
119                    'ford@example.com',
120                    'user',
121                ),
122                'orig'   => 'importuser,"Ford Prefect",ford@example.com,user'.NL,
123            ),
124        );
125
126        $this->doImportTest($csv, true, array(), $failures);
127    }
128
129    public function test_importUtf8()
130    {
131        $csv = 'User,"Real Name",Email,Groups
132importutf8,"Førd Prefect",ford@example.com,user
133';
134        $expected = array(
135            'importutf8' => array(
136                'name'  => 'Førd Prefect',
137                'mail'  => 'ford@example.com',
138                'grps'  => array('user'),
139            ),
140        );
141
142        $this->doImportTest($csv, true, $expected, array());
143    }
144
145    /**
146     *  utf8: u+00F8 (ø) <=> 0xF8 :iso-8859-1
147     */
148    public function test_importIso8859()
149    {
150        $csv = 'User,"Real Name",Email,Groups
151importiso8859,"F'.chr(0xF8).'rd Prefect",ford@example.com,user
152';
153        $expected = array(
154            'importiso8859' => array(
155                'name'  => 'Førd Prefect',
156                'mail'  => 'ford@example.com',
157                'grps'  => array('user'),
158            ),
159        );
160
161        $this->doImportTest($csv, true, $expected, array());
162    }
163
164    private function stripPasswords($array)
165    {
166        foreach ($array as $user => $data) {
167            unset($array[$user]['pass']);
168        }
169        return $array;
170    }
171
172    private function countPasswords($array)
173    {
174        $count = 0;
175        foreach ($array as $user => $data) {
176            if (!empty($data['pass'])) {
177                $count++;
178            }
179        }
180        return $count;
181    }
182}
183