]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | ||
3 | require_once 'application/config/ConfigManager.php'; | |
4 | require_once 'tests/Updater/DummyUpdater.php'; | |
5 | ||
6 | /** | |
7 | * Class UpdaterTest. | |
8 | * Runs unit tests against the Updater class. | |
9 | */ | |
10 | class UpdaterTest extends PHPUnit_Framework_TestCase | |
11 | { | |
12 | /** | |
13 | * @var string Path to test datastore. | |
14 | */ | |
15 | protected static $testDatastore = 'sandbox/datastore.php'; | |
16 | ||
17 | /** | |
18 | * @var string Config file path (without extension). | |
19 | */ | |
20 | protected static $configFile = 'tests/utils/config/configJson'; | |
21 | ||
22 | /** | |
23 | * @var ConfigManager | |
24 | */ | |
25 | protected $conf; | |
26 | ||
27 | /** | |
28 | * Executed before each test. | |
29 | */ | |
30 | public function setUp() | |
31 | { | |
32 | $this->conf = new ConfigManager(self::$configFile); | |
33 | } | |
34 | ||
35 | /** | |
36 | * Test read_updates_file with an empty/missing file. | |
37 | */ | |
38 | public function testReadEmptyUpdatesFile() | |
39 | { | |
40 | $this->assertEquals(array(), read_updates_file('')); | |
41 | $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; | |
42 | touch($updatesFile); | |
43 | $this->assertEquals(array(), read_updates_file($updatesFile)); | |
44 | unlink($updatesFile); | |
45 | } | |
46 | ||
47 | /** | |
48 | * Test read/write updates file. | |
49 | */ | |
50 | public function testReadWriteUpdatesFile() | |
51 | { | |
52 | $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; | |
53 | $updatesMethods = array('m1', 'm2', 'm3'); | |
54 | ||
55 | write_updates_file($updatesFile, $updatesMethods); | |
56 | $readMethods = read_updates_file($updatesFile); | |
57 | $this->assertEquals($readMethods, $updatesMethods); | |
58 | ||
59 | // Update | |
60 | $updatesMethods[] = 'm4'; | |
61 | write_updates_file($updatesFile, $updatesMethods); | |
62 | $readMethods = read_updates_file($updatesFile); | |
63 | $this->assertEquals($readMethods, $updatesMethods); | |
64 | unlink($updatesFile); | |
65 | } | |
66 | ||
67 | /** | |
68 | * Test errors in write_updates_file(): empty updates file. | |
69 | * | |
70 | * @expectedException Exception | |
71 | * @expectedExceptionMessageRegExp /Updates file path is not set(.*)/ | |
72 | */ | |
73 | public function testWriteEmptyUpdatesFile() | |
74 | { | |
75 | write_updates_file('', array('test')); | |
76 | } | |
77 | ||
78 | /** | |
79 | * Test errors in write_updates_file(): not writable updates file. | |
80 | * | |
81 | * @expectedException Exception | |
82 | * @expectedExceptionMessageRegExp /Unable to write(.*)/ | |
83 | */ | |
84 | public function testWriteUpdatesFileNotWritable() | |
85 | { | |
86 | $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; | |
87 | touch($updatesFile); | |
88 | chmod($updatesFile, 0444); | |
89 | try { | |
90 | @write_updates_file($updatesFile, array('test')); | |
91 | } catch (Exception $e) { | |
92 | unlink($updatesFile); | |
93 | throw $e; | |
94 | } | |
95 | } | |
96 | ||
97 | /** | |
98 | * Test the update() method, with no update to run. | |
99 | * 1. Everything already run. | |
100 | * 2. User is logged out. | |
101 | */ | |
102 | public function testNoUpdates() | |
103 | { | |
104 | $updates = array( | |
105 | 'updateMethodDummy1', | |
106 | 'updateMethodDummy2', | |
107 | 'updateMethodDummy3', | |
108 | 'updateMethodException', | |
109 | ); | |
110 | $updater = new DummyUpdater($updates, array(), $this->conf, true); | |
111 | $this->assertEquals(array(), $updater->update()); | |
112 | ||
113 | $updater = new DummyUpdater(array(), array(), $this->conf, false); | |
114 | $this->assertEquals(array(), $updater->update()); | |
115 | } | |
116 | ||
117 | /** | |
118 | * Test the update() method, with all updates to run (except the failing one). | |
119 | */ | |
120 | public function testUpdatesFirstTime() | |
121 | { | |
122 | $updates = array('updateMethodException',); | |
123 | $expectedUpdates = array( | |
124 | 'updateMethodDummy1', | |
125 | 'updateMethodDummy2', | |
126 | 'updateMethodDummy3', | |
127 | ); | |
128 | $updater = new DummyUpdater($updates, array(), $this->conf, true); | |
129 | $this->assertEquals($expectedUpdates, $updater->update()); | |
130 | } | |
131 | ||
132 | /** | |
133 | * Test the update() method, only one update to run. | |
134 | */ | |
135 | public function testOneUpdate() | |
136 | { | |
137 | $updates = array( | |
138 | 'updateMethodDummy1', | |
139 | 'updateMethodDummy3', | |
140 | 'updateMethodException', | |
141 | ); | |
142 | $expectedUpdate = array('updateMethodDummy2'); | |
143 | ||
144 | $updater = new DummyUpdater($updates, array(), $this->conf, true); | |
145 | $this->assertEquals($expectedUpdate, $updater->update()); | |
146 | } | |
147 | ||
148 | /** | |
149 | * Test Update failed. | |
150 | * | |
151 | * @expectedException UpdaterException | |
152 | */ | |
153 | public function testUpdateFailed() | |
154 | { | |
155 | $updates = array( | |
156 | 'updateMethodDummy1', | |
157 | 'updateMethodDummy2', | |
158 | 'updateMethodDummy3', | |
159 | ); | |
160 | ||
161 | $updater = new DummyUpdater($updates, array(), $this->conf, true); | |
162 | $updater->update(); | |
163 | } | |
164 | ||
165 | /** | |
166 | * Test update mergeDeprecatedConfig: | |
167 | * 1. init a config file. | |
168 | * 2. init a options.php file with update value. | |
169 | * 3. merge. | |
170 | * 4. check updated value in config file. | |
171 | */ | |
172 | public function testUpdateMergeDeprecatedConfig() | |
173 | { | |
174 | $this->conf->setConfigFile('tests/utils/config/configPhp'); | |
175 | $this->conf->reset(); | |
176 | ||
177 | $optionsFile = 'tests/Updater/options.php'; | |
178 | $options = '<?php | |
179 | $GLOBALS[\'privateLinkByDefault\'] = true;'; | |
180 | file_put_contents($optionsFile, $options); | |
181 | ||
182 | // tmp config file. | |
183 | $this->conf->setConfigFile('tests/Updater/config'); | |
184 | ||
185 | // merge configs | |
186 | $updater = new Updater(array(), array(), $this->conf, true); | |
187 | // This writes a new config file in tests/Updater/config.php | |
188 | $updater->updateMethodMergeDeprecatedConfigFile(); | |
189 | ||
190 | // make sure updated field is changed | |
191 | $this->conf->reload(); | |
192 | $this->assertTrue($this->conf->get('privacy.default_private_links')); | |
193 | $this->assertFalse(is_file($optionsFile)); | |
194 | // Delete the generated file. | |
195 | unlink($this->conf->getConfigFileExt()); | |
196 | } | |
197 | ||
198 | /** | |
199 | * Test mergeDeprecatedConfig in without options file. | |
200 | */ | |
201 | public function testMergeDeprecatedConfigNoFile() | |
202 | { | |
203 | $updater = new Updater(array(), array(), $this->conf, true); | |
204 | $updater->updateMethodMergeDeprecatedConfigFile(); | |
205 | ||
206 | $this->assertEquals('root', $this->conf->get('credentials.login')); | |
207 | } | |
208 | ||
209 | /** | |
210 | * Test renameDashTags update method. | |
211 | */ | |
212 | public function testRenameDashTags() | |
213 | { | |
214 | $refDB = new ReferenceLinkDB(); | |
215 | $refDB->write(self::$testDatastore); | |
216 | $linkDB = new LinkDB(self::$testDatastore, true, false); | |
217 | ||
218 | $this->assertEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); | |
219 | $updater = new Updater(array(), $linkDB, $this->conf, true); | |
220 | $updater->updateMethodRenameDashTags(); | |
221 | $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); | |
222 | } | |
223 | ||
224 | /** | |
225 | * Convert old PHP config file to JSON config. | |
226 | */ | |
227 | public function testConfigToJson() | |
228 | { | |
229 | $configFile = 'tests/utils/config/configPhp'; | |
230 | $this->conf->setConfigFile($configFile); | |
231 | $this->conf->reset(); | |
232 | ||
233 | // The ConfigIO is initialized with ConfigPhp. | |
234 | $this->assertTrue($this->conf->getConfigIO() instanceof ConfigPhp); | |
235 | ||
236 | $updater = new Updater(array(), array(), $this->conf, false); | |
237 | $done = $updater->updateMethodConfigToJson(); | |
238 | $this->assertTrue($done); | |
239 | ||
240 | // The ConfigIO has been updated to ConfigJson. | |
241 | $this->assertTrue($this->conf->getConfigIO() instanceof ConfigJson); | |
242 | $this->assertTrue(file_exists($this->conf->getConfigFileExt())); | |
243 | ||
244 | // Check JSON config data. | |
245 | $this->conf->reload(); | |
246 | $this->assertEquals('root', $this->conf->get('credentials.login')); | |
247 | $this->assertEquals('lala', $this->conf->get('redirector.url')); | |
248 | $this->assertEquals('data/datastore.php', $this->conf->get('resource.datastore')); | |
249 | $this->assertEquals('1', $this->conf->get('plugins.WALLABAG_VERSION')); | |
250 | ||
251 | rename($configFile . '.save.php', $configFile . '.php'); | |
252 | unlink($this->conf->getConfigFileExt()); | |
253 | } | |
254 | ||
255 | /** | |
256 | * Launch config conversion update with an existing JSON file => nothing to do. | |
257 | */ | |
258 | public function testConfigToJsonNothingToDo() | |
259 | { | |
260 | $filetime = filemtime($this->conf->getConfigFileExt()); | |
261 | $updater = new Updater(array(), array(), $this->conf, false); | |
262 | $done = $updater->updateMethodConfigToJson(); | |
263 | $this->assertTrue($done); | |
264 | $expected = filemtime($this->conf->getConfigFileExt()); | |
265 | $this->assertEquals($expected, $filetime); | |
266 | } | |
267 | ||
268 | /** | |
269 | * Test escapeUnescapedConfig with valid data. | |
270 | */ | |
271 | public function testEscapeConfig() | |
272 | { | |
273 | $sandbox = 'sandbox/config'; | |
274 | copy(self::$configFile .'.json.php', $sandbox .'.json.php'); | |
275 | $this->conf = new ConfigManager($sandbox); | |
276 | $title = '<script>alert("title");</script>'; | |
277 | $headerLink = '<script>alert("header_link");</script>'; | |
278 | $redirectorUrl = '<script>alert("redirector");</script>'; | |
279 | $this->conf->set('general.title', $title); | |
280 | $this->conf->set('general.header_link', $headerLink); | |
281 | $this->conf->set('redirector.url', $redirectorUrl); | |
282 | $updater = new Updater(array(), array(), $this->conf, true); | |
283 | $done = $updater->updateMethodEscapeUnescapedConfig(); | |
284 | $this->assertTrue($done); | |
285 | $this->conf->reload(); | |
286 | $this->assertEquals(escape($title), $this->conf->get('general.title')); | |
287 | $this->assertEquals(escape($headerLink), $this->conf->get('general.header_link')); | |
288 | $this->assertEquals(escape($redirectorUrl), $this->conf->get('redirector.url')); | |
289 | unlink($sandbox .'.json.php'); | |
290 | } | |
291 | ||
292 | /** | |
293 | * Test updateMethodDatastoreIds(). | |
294 | */ | |
295 | public function testDatastoreIds() | |
296 | { | |
297 | $links = array( | |
298 | '20121206_182539' => array( | |
299 | 'linkdate' => '20121206_182539', | |
300 | 'title' => 'Geek and Poke', | |
301 | 'url' => 'http://geek-and-poke.com/', | |
302 | 'description' => 'desc', | |
303 | 'tags' => 'dev cartoon tag1 tag2 tag3 tag4 ', | |
304 | 'updated' => '20121206_190301', | |
305 | 'private' => false, | |
306 | ), | |
307 | '20121206_172539' => array( | |
308 | 'linkdate' => '20121206_172539', | |
309 | 'title' => 'UserFriendly - Samba', | |
310 | 'url' => 'http://ars.userfriendly.org/cartoons/?id=20010306', | |
311 | 'description' => '', | |
312 | 'tags' => 'samba cartoon web', | |
313 | 'private' => false, | |
314 | ), | |
315 | '20121206_142300' => array( | |
316 | 'linkdate' => '20121206_142300', | |
317 | 'title' => 'UserFriendly - Web Designer', | |
318 | 'url' => 'http://ars.userfriendly.org/cartoons/?id=20121206', | |
319 | 'description' => 'Naming conventions... #private', | |
320 | 'tags' => 'samba cartoon web', | |
321 | 'private' => true, | |
322 | ), | |
323 | ); | |
324 | $refDB = new ReferenceLinkDB(); | |
325 | $refDB->setLinks($links); | |
326 | $refDB->write(self::$testDatastore); | |
327 | $linkDB = new LinkDB(self::$testDatastore, true, false); | |
328 | ||
329 | $checksum = hash_file('sha1', self::$testDatastore); | |
330 | ||
331 | $this->conf->set('resource.data_dir', 'sandbox'); | |
332 | $this->conf->set('resource.datastore', self::$testDatastore); | |
333 | ||
334 | $updater = new Updater(array(), $linkDB, $this->conf, true); | |
335 | $this->assertTrue($updater->updateMethodDatastoreIds()); | |
336 | ||
337 | $linkDB = new LinkDB(self::$testDatastore, true, false); | |
338 | ||
339 | $backup = glob($this->conf->get('resource.data_dir') . '/datastore.'. date('YmdH') .'*.php'); | |
340 | $backup = $backup[0]; | |
341 | ||
342 | $this->assertFileExists($backup); | |
343 | $this->assertEquals($checksum, hash_file('sha1', $backup)); | |
344 | unlink($backup); | |
345 | ||
346 | $this->assertEquals(3, count($linkDB)); | |
347 | $this->assertTrue(isset($linkDB[0])); | |
348 | $this->assertFalse(isset($linkDB[0]['linkdate'])); | |
349 | $this->assertEquals(0, $linkDB[0]['id']); | |
350 | $this->assertEquals('UserFriendly - Web Designer', $linkDB[0]['title']); | |
351 | $this->assertEquals('http://ars.userfriendly.org/cartoons/?id=20121206', $linkDB[0]['url']); | |
352 | $this->assertEquals('Naming conventions... #private', $linkDB[0]['description']); | |
353 | $this->assertEquals('samba cartoon web', $linkDB[0]['tags']); | |
354 | $this->assertTrue($linkDB[0]['private']); | |
355 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'), $linkDB[0]['created']); | |
356 | ||
357 | $this->assertTrue(isset($linkDB[1])); | |
358 | $this->assertFalse(isset($linkDB[1]['linkdate'])); | |
359 | $this->assertEquals(1, $linkDB[1]['id']); | |
360 | $this->assertEquals('UserFriendly - Samba', $linkDB[1]['title']); | |
361 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'), $linkDB[1]['created']); | |
362 | ||
363 | $this->assertTrue(isset($linkDB[2])); | |
364 | $this->assertFalse(isset($linkDB[2]['linkdate'])); | |
365 | $this->assertEquals(2, $linkDB[2]['id']); | |
366 | $this->assertEquals('Geek and Poke', $linkDB[2]['title']); | |
367 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'), $linkDB[2]['created']); | |
368 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_190301'), $linkDB[2]['updated']); | |
369 | } | |
370 | ||
371 | /** | |
372 | * Test updateMethodDatastoreIds() with the update already applied: nothing to do. | |
373 | */ | |
374 | public function testDatastoreIdsNothingToDo() | |
375 | { | |
376 | $refDB = new ReferenceLinkDB(); | |
377 | $refDB->write(self::$testDatastore); | |
378 | $linkDB = new LinkDB(self::$testDatastore, true, false); | |
379 | ||
380 | $this->conf->set('resource.data_dir', 'sandbox'); | |
381 | $this->conf->set('resource.datastore', self::$testDatastore); | |
382 | ||
383 | $checksum = hash_file('sha1', self::$testDatastore); | |
384 | $updater = new Updater(array(), $linkDB, $this->conf, true); | |
385 | $this->assertTrue($updater->updateMethodDatastoreIds()); | |
386 | $this->assertEquals($checksum, hash_file('sha1', self::$testDatastore)); | |
387 | } | |
388 | ||
389 | /** | |
390 | * Test updateMethodEscapeMarkdown with markdown plugin enabled | |
391 | * => setting markdown_escape set to false. | |
392 | */ | |
393 | public function testEscapeMarkdownSettingToFalse() | |
394 | { | |
395 | $sandboxConf = 'sandbox/config'; | |
396 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | |
397 | $this->conf = new ConfigManager($sandboxConf); | |
398 | ||
399 | $this->conf->set('general.enabled_plugins', array('markdown')); | |
400 | $updater = new Updater(array(), array(), $this->conf, true); | |
401 | $this->assertTrue($updater->updateMethodEscapeMarkdown()); | |
402 | $this->assertFalse($this->conf->get('security.markdown_escape')); | |
403 | ||
404 | // reload from file | |
405 | $this->conf = new ConfigManager($sandboxConf); | |
406 | $this->assertFalse($this->conf->get('security.markdown_escape')); | |
407 | } | |
408 | ||
409 | /** | |
410 | * Test updateMethodEscapeMarkdown with markdown plugin disabled | |
411 | * => setting markdown_escape set to true. | |
412 | */ | |
413 | public function testEscapeMarkdownSettingToTrue() | |
414 | { | |
415 | $sandboxConf = 'sandbox/config'; | |
416 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | |
417 | $this->conf = new ConfigManager($sandboxConf); | |
418 | ||
419 | $this->conf->set('general.enabled_plugins', array()); | |
420 | $updater = new Updater(array(), array(), $this->conf, true); | |
421 | $this->assertTrue($updater->updateMethodEscapeMarkdown()); | |
422 | $this->assertTrue($this->conf->get('security.markdown_escape')); | |
423 | ||
424 | // reload from file | |
425 | $this->conf = new ConfigManager($sandboxConf); | |
426 | $this->assertTrue($this->conf->get('security.markdown_escape')); | |
427 | } | |
428 | ||
429 | /** | |
430 | * Test updateMethodEscapeMarkdown with nothing to do (setting already enabled) | |
431 | */ | |
432 | public function testEscapeMarkdownSettingNothingToDoEnabled() | |
433 | { | |
434 | $sandboxConf = 'sandbox/config'; | |
435 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | |
436 | $this->conf = new ConfigManager($sandboxConf); | |
437 | $this->conf->set('security.markdown_escape', true); | |
438 | $updater = new Updater(array(), array(), $this->conf, true); | |
439 | $this->assertTrue($updater->updateMethodEscapeMarkdown()); | |
440 | $this->assertTrue($this->conf->get('security.markdown_escape')); | |
441 | } | |
442 | ||
443 | /** | |
444 | * Test updateMethodEscapeMarkdown with nothing to do (setting already disabled) | |
445 | */ | |
446 | public function testEscapeMarkdownSettingNothingToDoDisabled() | |
447 | { | |
448 | $this->conf->set('security.markdown_escape', false); | |
449 | $updater = new Updater(array(), array(), $this->conf, true); | |
450 | $this->assertTrue($updater->updateMethodEscapeMarkdown()); | |
451 | $this->assertFalse($this->conf->get('security.markdown_escape')); | |
452 | } | |
453 | } |