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