diff options
author | ArthurHoaro <arthur@hoa.ro> | 2016-05-29 12:32:14 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2016-06-11 09:30:56 +0200 |
commit | b74b96bfbd0b778ac50fd17f5e107c51435b1678 (patch) | |
tree | fd2debc510c2c51e9b75e2081a31a10e9c02ad06 | |
parent | 684e662a58b02bde225e44d3677987b6fc3adf0b (diff) | |
download | Shaarli-b74b96bfbd0b778ac50fd17f5e107c51435b1678.tar.gz Shaarli-b74b96bfbd0b778ac50fd17f5e107c51435b1678.tar.zst Shaarli-b74b96bfbd0b778ac50fd17f5e107c51435b1678.zip |
Adds ConfigJson which handle the configuration in JSON format.
Also use the Updater to make the transition
-rw-r--r-- | application/PageBuilder.php | 1 | ||||
-rw-r--r-- | application/Updater.php | 43 | ||||
-rw-r--r-- | application/config/ConfigIO.php | 2 | ||||
-rw-r--r-- | application/config/ConfigJson.php | 66 | ||||
-rw-r--r-- | application/config/ConfigManager.php | 7 | ||||
-rw-r--r-- | tests/Updater/UpdaterTest.php | 66 | ||||
-rw-r--r-- | tests/config/ConfigJsonTest.php | 125 | ||||
-rw-r--r-- | tests/config/ConfigManagerTest.php | 146 | ||||
-rw-r--r-- | tests/utils/config/configInvalid.json.php | 4 | ||||
-rw-r--r-- | tests/utils/config/configJson.json.php | 19 | ||||
-rw-r--r-- | tests/utils/config/configUpdateDone.json.php | 4 | ||||
-rw-r--r-- | tpl/linklist.html | 2 | ||||
-rw-r--r-- | tpl/tools.html | 2 |
13 files changed, 462 insertions, 25 deletions
diff --git a/application/PageBuilder.php b/application/PageBuilder.php index cf13c714..1d3ba9e8 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php | |||
@@ -75,6 +75,7 @@ class PageBuilder | |||
75 | $this->tpl->assign('shaarlititle', $conf->get('title', 'Shaarli')); | 75 | $this->tpl->assign('shaarlititle', $conf->get('title', 'Shaarli')); |
76 | $this->tpl->assign('openshaarli', $conf->get('config.OPEN_SHAARLI', false)); | 76 | $this->tpl->assign('openshaarli', $conf->get('config.OPEN_SHAARLI', false)); |
77 | $this->tpl->assign('showatom', $conf->get('config.SHOW_ATOM', false)); | 77 | $this->tpl->assign('showatom', $conf->get('config.SHOW_ATOM', false)); |
78 | $this->tpl->assign('hide_timestamps', $conf->get('config.HIDE_TIMESTAMPS', false)); | ||
78 | // FIXME! Globals | 79 | // FIXME! Globals |
79 | if (!empty($GLOBALS['plugin_errors'])) { | 80 | if (!empty($GLOBALS['plugin_errors'])) { |
80 | $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']); | 81 | $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']); |
diff --git a/application/Updater.php b/application/Updater.php index 6b92af3d..8552850c 100644 --- a/application/Updater.php +++ b/application/Updater.php | |||
@@ -142,6 +142,48 @@ class Updater | |||
142 | $this->linkDB->savedb($conf->get('config.PAGECACHE')); | 142 | $this->linkDB->savedb($conf->get('config.PAGECACHE')); |
143 | return true; | 143 | return true; |
144 | } | 144 | } |
145 | |||
146 | /** | ||
147 | * Move old configuration in PHP to the new config system in JSON format. | ||
148 | * | ||
149 | * Will rename 'config.php' into 'config.save.php' and create 'config.json'. | ||
150 | */ | ||
151 | public function updateMethodConfigToJson() | ||
152 | { | ||
153 | $conf = ConfigManager::getInstance(); | ||
154 | |||
155 | // JSON config already exists, nothing to do. | ||
156 | if ($conf->getConfigIO() instanceof ConfigJson) { | ||
157 | return true; | ||
158 | } | ||
159 | |||
160 | $configPhp = new ConfigPhp(); | ||
161 | $configJson = new ConfigJson(); | ||
162 | $oldConfig = $configPhp->read($conf::$CONFIG_FILE . '.php'); | ||
163 | rename($conf->getConfigFile(), $conf::$CONFIG_FILE . '.save.php'); | ||
164 | $conf->setConfigIO($configJson); | ||
165 | $conf->reload(); | ||
166 | |||
167 | foreach (ConfigPhp::$ROOT_KEYS as $key) { | ||
168 | $conf->set($key, $oldConfig[$key]); | ||
169 | } | ||
170 | |||
171 | // Set sub config keys (config and plugins) | ||
172 | $subConfig = array('config', 'plugins'); | ||
173 | foreach ($subConfig as $sub) { | ||
174 | foreach ($oldConfig[$sub] as $key => $value) { | ||
175 | $conf->set($sub .'.'. $key, $value); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | try{ | ||
180 | $conf->write($this->isLoggedIn); | ||
181 | return true; | ||
182 | } catch (IOException $e) { | ||
183 | error_log($e->getMessage()); | ||
184 | return false; | ||
185 | } | ||
186 | } | ||
145 | } | 187 | } |
146 | 188 | ||
147 | /** | 189 | /** |
@@ -199,7 +241,6 @@ class UpdaterException extends Exception | |||
199 | } | 241 | } |
200 | } | 242 | } |
201 | 243 | ||
202 | |||
203 | /** | 244 | /** |
204 | * Read the updates file, and return already done updates. | 245 | * Read the updates file, and return already done updates. |
205 | * | 246 | * |
diff --git a/application/config/ConfigIO.php b/application/config/ConfigIO.php index 4b1c9901..2b68fe6a 100644 --- a/application/config/ConfigIO.php +++ b/application/config/ConfigIO.php | |||
@@ -21,8 +21,6 @@ interface ConfigIO | |||
21 | * | 21 | * |
22 | * @param string $filepath Config file absolute path. | 22 | * @param string $filepath Config file absolute path. |
23 | * @param array $conf All configuration in an array. | 23 | * @param array $conf All configuration in an array. |
24 | * | ||
25 | * @return bool True if the configuration has been successfully written, false otherwise. | ||
26 | */ | 24 | */ |
27 | function write($filepath, $conf); | 25 | function write($filepath, $conf); |
28 | 26 | ||
diff --git a/application/config/ConfigJson.php b/application/config/ConfigJson.php new file mode 100644 index 00000000..cbafbf6d --- /dev/null +++ b/application/config/ConfigJson.php | |||
@@ -0,0 +1,66 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Class ConfigJson (ConfigIO implementation) | ||
5 | * | ||
6 | * Handle Shaarli's JSON configuration file. | ||
7 | */ | ||
8 | class ConfigJson implements ConfigIO | ||
9 | { | ||
10 | /** | ||
11 | * The JSON data is wrapped in a PHP file for security purpose. | ||
12 | * This way, even if the file is accessible, credentials and configuration won't be exposed. | ||
13 | * | ||
14 | * @var string PHP start tag and comment tag. | ||
15 | */ | ||
16 | public static $PHP_HEADER; | ||
17 | |||
18 | public function __construct() | ||
19 | { | ||
20 | // The field can't be initialized directly with concatenation before PHP 5.6. | ||
21 | self::$PHP_HEADER = '<?php /*'. PHP_EOL; | ||
22 | } | ||
23 | |||
24 | /** | ||
25 | * @inheritdoc | ||
26 | */ | ||
27 | function read($filepath) | ||
28 | { | ||
29 | if (! file_exists($filepath) || ! is_readable($filepath)) { | ||
30 | return array(); | ||
31 | } | ||
32 | $data = file_get_contents($filepath); | ||
33 | $data = str_replace(self::$PHP_HEADER, '', $data); | ||
34 | $data = json_decode($data, true); | ||
35 | if ($data === null) { | ||
36 | $error = json_last_error(); | ||
37 | throw new Exception('An error occured while parsing JSON file: error code #'. $error); | ||
38 | } | ||
39 | return $data; | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * @inheritdoc | ||
44 | */ | ||
45 | function write($filepath, $conf) | ||
46 | { | ||
47 | // JSON_PRETTY_PRINT is available from PHP 5.4. | ||
48 | $print = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0; | ||
49 | $data = self::$PHP_HEADER . json_encode($conf, $print); | ||
50 | if (!file_put_contents($filepath, $data)) { | ||
51 | throw new IOException( | ||
52 | $filepath, | ||
53 | 'Shaarli could not create the config file. | ||
54 | Please make sure Shaarli has the right to write in the folder is it installed in.' | ||
55 | ); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * @inheritdoc | ||
61 | */ | ||
62 | function getExtension() | ||
63 | { | ||
64 | return '.json.php'; | ||
65 | } | ||
66 | } | ||
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index 212aac05..70456737 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php | |||
@@ -3,7 +3,7 @@ | |||
3 | // FIXME! Namespaces... | 3 | // FIXME! Namespaces... |
4 | require_once 'ConfigIO.php'; | 4 | require_once 'ConfigIO.php'; |
5 | require_once 'ConfigPhp.php'; | 5 | require_once 'ConfigPhp.php'; |
6 | #require_once 'ConfigJson.php'; | 6 | require_once 'ConfigJson.php'; |
7 | 7 | ||
8 | /** | 8 | /** |
9 | * Class ConfigManager | 9 | * Class ConfigManager |
@@ -84,12 +84,11 @@ class ConfigManager | |||
84 | */ | 84 | */ |
85 | protected function initialize() | 85 | protected function initialize() |
86 | { | 86 | { |
87 | /*if (! file_exists(self::$CONFIG_FILE .'.php')) { | 87 | if (! file_exists(self::$CONFIG_FILE .'.php')) { |
88 | $this->configIO = new ConfigJson(); | 88 | $this->configIO = new ConfigJson(); |
89 | } else { | 89 | } else { |
90 | $this->configIO = new ConfigPhp(); | 90 | $this->configIO = new ConfigPhp(); |
91 | }*/ | 91 | } |
92 | $this->configIO = new ConfigPhp(); | ||
93 | $this->load(); | 92 | $this->load(); |
94 | } | 93 | } |
95 | 94 | ||
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 8bfb4ba3..f8de2f70 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php | |||
@@ -20,9 +20,9 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
20 | protected static $testDatastore = 'sandbox/datastore.php'; | 20 | protected static $testDatastore = 'sandbox/datastore.php'; |
21 | 21 | ||
22 | /** | 22 | /** |
23 | * @var string Config file path. | 23 | * @var string Config file path (without extension). |
24 | */ | 24 | */ |
25 | protected static $configFile = 'tests/Updater/config.php'; | 25 | protected static $configFile = 'tests/utils/config/configUpdater'; |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * @var ConfigManager | 28 | * @var ConfigManager |
@@ -52,8 +52,9 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
52 | ) | 52 | ) |
53 | ); | 53 | ); |
54 | 54 | ||
55 | ConfigManager::$CONFIG_FILE = 'tests/Updater/config'; | 55 | ConfigManager::$CONFIG_FILE = self::$configFile; |
56 | $this->conf = ConfigManager::getInstance(); | 56 | $this->conf = ConfigManager::reset(); |
57 | $this->conf->reload(); | ||
57 | foreach (self::$configFields as $key => $value) { | 58 | foreach (self::$configFields as $key => $value) { |
58 | $this->conf->set($key, $value); | 59 | $this->conf->set($key, $value); |
59 | } | 60 | } |
@@ -67,8 +68,8 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
67 | */ | 68 | */ |
68 | public function tearDown() | 69 | public function tearDown() |
69 | { | 70 | { |
70 | if (is_file(self::$configFile)) { | 71 | if (is_file('tests/Updater/config.json')) { |
71 | unlink(self::$configFile); | 72 | unlink('tests/Updater/config.json'); |
72 | } | 73 | } |
73 | 74 | ||
74 | if (is_file(self::$configFields['config']['DATADIR'] . '/options.php')) { | 75 | if (is_file(self::$configFields['config']['DATADIR'] . '/options.php')) { |
@@ -214,6 +215,8 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
214 | { | 215 | { |
215 | // Use writeConfig to create a options.php | 216 | // Use writeConfig to create a options.php |
216 | ConfigManager::$CONFIG_FILE = 'tests/Updater/options'; | 217 | ConfigManager::$CONFIG_FILE = 'tests/Updater/options'; |
218 | $this->conf->setConfigIO(new ConfigPhp()); | ||
219 | |||
217 | $invert = !$this->conf->get('privateLinkByDefault'); | 220 | $invert = !$this->conf->get('privateLinkByDefault'); |
218 | $this->conf->set('privateLinkByDefault', $invert); | 221 | $this->conf->set('privateLinkByDefault', $invert); |
219 | $this->conf->write(true); | 222 | $this->conf->write(true); |
@@ -225,12 +228,15 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
225 | 228 | ||
226 | // merge configs | 229 | // merge configs |
227 | $updater = new Updater(array(), array(), true); | 230 | $updater = new Updater(array(), array(), true); |
231 | // This writes a new config file in tests/Updater/config.php | ||
228 | $updater->updateMethodMergeDeprecatedConfigFile(); | 232 | $updater->updateMethodMergeDeprecatedConfigFile(); |
229 | 233 | ||
230 | // make sure updated field is changed | 234 | // make sure updated field is changed |
231 | $this->conf->reload(); | 235 | $this->conf->reload(); |
232 | $this->assertEquals($invert, $this->conf->get('privateLinkByDefault')); | 236 | $this->assertEquals($invert, $this->conf->get('privateLinkByDefault')); |
233 | $this->assertFalse(is_file($optionsFile)); | 237 | $this->assertFalse(is_file($optionsFile)); |
238 | // Delete the generated file. | ||
239 | unlink($this->conf->getConfigFile()); | ||
234 | } | 240 | } |
235 | 241 | ||
236 | /** | 242 | /** |
@@ -257,4 +263,52 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
257 | $updater->updateMethodRenameDashTags(); | 263 | $updater->updateMethodRenameDashTags(); |
258 | $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); | 264 | $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); |
259 | } | 265 | } |
266 | |||
267 | /** | ||
268 | * Convert old PHP config file to JSON config. | ||
269 | */ | ||
270 | public function testConfigToJson() | ||
271 | { | ||
272 | $configFile = 'tests/utils/config/configPhp'; | ||
273 | ConfigManager::$CONFIG_FILE = $configFile; | ||
274 | $conf = ConfigManager::reset(); | ||
275 | |||
276 | // The ConfigIO is initialized with ConfigPhp. | ||
277 | $this->assertTrue($conf->getConfigIO() instanceof ConfigPhp); | ||
278 | |||
279 | $updater = new Updater(array(), array(), false); | ||
280 | $done = $updater->updateMethodConfigToJson(); | ||
281 | $this->assertTrue($done); | ||
282 | |||
283 | // The ConfigIO has been updated to ConfigJson. | ||
284 | $this->assertTrue($conf->getConfigIO() instanceof ConfigJson); | ||
285 | $this->assertTrue(file_exists($conf->getConfigFile())); | ||
286 | |||
287 | // Check JSON config data. | ||
288 | $conf->reload(); | ||
289 | $this->assertEquals('root', $conf->get('login')); | ||
290 | $this->assertEquals('lala', $conf->get('redirector')); | ||
291 | $this->assertEquals('data/datastore.php', $conf->get('config.DATASTORE')); | ||
292 | $this->assertEquals('1', $conf->get('plugins.WALLABAG_VERSION')); | ||
293 | |||
294 | rename($configFile . '.save.php', $configFile . '.php'); | ||
295 | unlink($conf->getConfigFile()); | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * Launch config conversion update with an existing JSON file => nothing to do. | ||
300 | */ | ||
301 | public function testConfigToJsonNothingToDo() | ||
302 | { | ||
303 | $configFile = 'tests/utils/config/configUpdateDone'; | ||
304 | ConfigManager::$CONFIG_FILE = $configFile; | ||
305 | $conf = ConfigManager::reset(); | ||
306 | $conf->reload(); | ||
307 | $filetime = filemtime($conf->getConfigFile()); | ||
308 | $updater = new Updater(array(), array(), false); | ||
309 | $done = $updater->updateMethodConfigToJson(); | ||
310 | $this->assertTrue($done); | ||
311 | $expected = filemtime($conf->getConfigFile()); | ||
312 | $this->assertEquals($expected, $filetime); | ||
313 | } | ||
260 | } | 314 | } |
diff --git a/tests/config/ConfigJsonTest.php b/tests/config/ConfigJsonTest.php new file mode 100644 index 00000000..5b3bce46 --- /dev/null +++ b/tests/config/ConfigJsonTest.php | |||
@@ -0,0 +1,125 @@ | |||
1 | <?php | ||
2 | |||
3 | require_once 'application/config/ConfigJson.php'; | ||
4 | |||
5 | /** | ||
6 | * Class ConfigJsonTest | ||
7 | */ | ||
8 | class ConfigJsonTest extends PHPUnit_Framework_TestCase | ||
9 | { | ||
10 | /** | ||
11 | * @var ConfigJson | ||
12 | */ | ||
13 | protected $configIO; | ||
14 | |||
15 | public function setUp() | ||
16 | { | ||
17 | $this->configIO = new ConfigJson(); | ||
18 | } | ||
19 | |||
20 | /** | ||
21 | * Read a simple existing config file. | ||
22 | */ | ||
23 | public function testRead() | ||
24 | { | ||
25 | $conf = $this->configIO->read('tests/utils/config/configJson.json.php'); | ||
26 | $this->assertEquals('root', $conf['login']); | ||
27 | $this->assertEquals('lala', $conf['redirector']); | ||
28 | $this->assertEquals('data/datastore.php', $conf['config']['DATASTORE']); | ||
29 | $this->assertEquals('1', $conf['plugins']['WALLABAG_VERSION']); | ||
30 | } | ||
31 | |||
32 | /** | ||
33 | * Read a non existent config file -> empty array. | ||
34 | */ | ||
35 | public function testReadNonExistent() | ||
36 | { | ||
37 | $this->assertEquals(array(), $this->configIO->read('nope')); | ||
38 | } | ||
39 | |||
40 | /** | ||
41 | * Read a non existent config file -> empty array. | ||
42 | * | ||
43 | * @expectedException Exception | ||
44 | * @expectedExceptionMessage An error occured while parsing JSON file: error code #4 | ||
45 | */ | ||
46 | public function testReadInvalidJson() | ||
47 | { | ||
48 | $this->configIO->read('tests/utils/config/configInvalid.json.php'); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * Write a new config file. | ||
53 | */ | ||
54 | public function testWriteNew() | ||
55 | { | ||
56 | $dataFile = 'tests/utils/config/configWrite.json.php'; | ||
57 | $data = array( | ||
58 | 'login' => 'root', | ||
59 | 'redirector' => 'lala', | ||
60 | 'config' => array( | ||
61 | 'DATASTORE' => 'data/datastore.php', | ||
62 | ), | ||
63 | 'plugins' => array( | ||
64 | 'WALLABAG_VERSION' => '1', | ||
65 | ) | ||
66 | ); | ||
67 | $this->configIO->write($dataFile, $data); | ||
68 | // PHP 5.3 doesn't support json pretty print. | ||
69 | if (defined('JSON_PRETTY_PRINT')) { | ||
70 | $expected = '{ | ||
71 | "login": "root", | ||
72 | "redirector": "lala", | ||
73 | "config": { | ||
74 | "DATASTORE": "data\/datastore.php" | ||
75 | }, | ||
76 | "plugins": { | ||
77 | "WALLABAG_VERSION": "1" | ||
78 | } | ||
79 | }'; | ||
80 | } else { | ||
81 | $expected = '{"login":"root","redirector":"lala","config":{"DATASTORE":"data\/datastore.php"},"plugins":{"WALLABAG_VERSION":"1"}}'; | ||
82 | } | ||
83 | $expected = ConfigJson::$PHP_HEADER . $expected; | ||
84 | $this->assertEquals($expected, file_get_contents($dataFile)); | ||
85 | unlink($dataFile); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * Overwrite an existing setting. | ||
90 | */ | ||
91 | public function testOverwrite() | ||
92 | { | ||
93 | $source = 'tests/utils/config/configJson.json.php'; | ||
94 | $dest = 'tests/utils/config/configOverwrite.json.php'; | ||
95 | copy($source, $dest); | ||
96 | $conf = $this->configIO->read($dest); | ||
97 | $conf['redirector'] = 'blabla'; | ||
98 | $this->configIO->write($dest, $conf); | ||
99 | $conf = $this->configIO->read($dest); | ||
100 | $this->assertEquals('blabla', $conf['redirector']); | ||
101 | unlink($dest); | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * Write to invalid path. | ||
106 | * | ||
107 | * @expectedException IOException | ||
108 | */ | ||
109 | public function testWriteInvalidArray() | ||
110 | { | ||
111 | $conf = array('conf' => 'value'); | ||
112 | @$this->configIO->write(array(), $conf); | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * Write to invalid path. | ||
117 | * | ||
118 | * @expectedException IOException | ||
119 | */ | ||
120 | public function testWriteInvalidBlank() | ||
121 | { | ||
122 | $conf = array('conf' => 'value'); | ||
123 | @$this->configIO->write('', $conf); | ||
124 | } | ||
125 | } | ||
diff --git a/tests/config/ConfigManagerTest.php b/tests/config/ConfigManagerTest.php index 1b6358f3..7390699c 100644 --- a/tests/config/ConfigManagerTest.php +++ b/tests/config/ConfigManagerTest.php | |||
@@ -6,7 +6,7 @@ | |||
6 | * Note: it only test the manager with ConfigJson, | 6 | * Note: it only test the manager with ConfigJson, |
7 | * ConfigPhp is only a workaround to handle the transition to JSON type. | 7 | * ConfigPhp is only a workaround to handle the transition to JSON type. |
8 | */ | 8 | */ |
9 | class ConfigManagerTest extends \PHPUnit_Framework_TestCase | 9 | class ConfigManagerTest extends PHPUnit_Framework_TestCase |
10 | { | 10 | { |
11 | /** | 11 | /** |
12 | * @var ConfigManager | 12 | * @var ConfigManager |
@@ -15,28 +15,49 @@ class ConfigManagerTest extends \PHPUnit_Framework_TestCase | |||
15 | 15 | ||
16 | public function setUp() | 16 | public function setUp() |
17 | { | 17 | { |
18 | ConfigManager::$CONFIG_FILE = 'tests/config/config'; | 18 | ConfigManager::$CONFIG_FILE = 'tests/utils/config/configJson'; |
19 | $this->conf = ConfigManager::getInstance(); | 19 | $this->conf = ConfigManager::reset(); |
20 | } | 20 | } |
21 | 21 | ||
22 | public function tearDown() | 22 | /** |
23 | * Simple config test: | ||
24 | * 1. Set settings. | ||
25 | * 2. Check settings value. | ||
26 | */ | ||
27 | public function testSetGet() | ||
23 | { | 28 | { |
24 | @unlink($this->conf->getConfigFile()); | 29 | $this->conf->set('paramInt', 42); |
30 | $this->conf->set('paramString', 'value1'); | ||
31 | $this->conf->set('paramBool', false); | ||
32 | $this->conf->set('paramArray', array('foo' => 'bar')); | ||
33 | $this->conf->set('paramNull', null); | ||
34 | |||
35 | $this->assertEquals(42, $this->conf->get('paramInt')); | ||
36 | $this->assertEquals('value1', $this->conf->get('paramString')); | ||
37 | $this->assertFalse($this->conf->get('paramBool')); | ||
38 | $this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray')); | ||
39 | $this->assertEquals(null, $this->conf->get('paramNull')); | ||
25 | } | 40 | } |
26 | 41 | ||
42 | /** | ||
43 | * Set/write/get config test: | ||
44 | * 1. Set settings. | ||
45 | * 2. Write it to the config file. | ||
46 | * 3. Read the file. | ||
47 | * 4. Check settings value. | ||
48 | */ | ||
27 | public function testSetWriteGet() | 49 | public function testSetWriteGet() |
28 | { | 50 | { |
29 | // This won't work with ConfigPhp. | ||
30 | $this->markTestIncomplete(); | ||
31 | |||
32 | $this->conf->set('paramInt', 42); | 51 | $this->conf->set('paramInt', 42); |
33 | $this->conf->set('paramString', 'value1'); | 52 | $this->conf->set('paramString', 'value1'); |
34 | $this->conf->set('paramBool', false); | 53 | $this->conf->set('paramBool', false); |
35 | $this->conf->set('paramArray', array('foo' => 'bar')); | 54 | $this->conf->set('paramArray', array('foo' => 'bar')); |
36 | $this->conf->set('paramNull', null); | 55 | $this->conf->set('paramNull', null); |
37 | 56 | ||
57 | ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp'; | ||
38 | $this->conf->write(true); | 58 | $this->conf->write(true); |
39 | $this->conf->reload(); | 59 | $this->conf->reload(); |
60 | unlink($this->conf->getConfigFile()); | ||
40 | 61 | ||
41 | $this->assertEquals(42, $this->conf->get('paramInt')); | 62 | $this->assertEquals(42, $this->conf->get('paramInt')); |
42 | $this->assertEquals('value1', $this->conf->get('paramString')); | 63 | $this->assertEquals('value1', $this->conf->get('paramString')); |
@@ -44,5 +65,110 @@ class ConfigManagerTest extends \PHPUnit_Framework_TestCase | |||
44 | $this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray')); | 65 | $this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray')); |
45 | $this->assertEquals(null, $this->conf->get('paramNull')); | 66 | $this->assertEquals(null, $this->conf->get('paramNull')); |
46 | } | 67 | } |
47 | 68 | ||
48 | } \ No newline at end of file | 69 | /** |
70 | * Test set/write/get with nested keys. | ||
71 | */ | ||
72 | public function testSetWriteGetNested() | ||
73 | { | ||
74 | $this->conf->set('foo.bar.key.stuff', 'testSetWriteGetNested'); | ||
75 | |||
76 | ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp'; | ||
77 | $this->conf->write(true); | ||
78 | $this->conf->reload(); | ||
79 | unlink($this->conf->getConfigFile()); | ||
80 | |||
81 | $this->assertEquals('testSetWriteGetNested', $this->conf->get('foo.bar.key.stuff')); | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * Set with an empty key. | ||
86 | * | ||
87 | * @expectedException Exception | ||
88 | * @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*# | ||
89 | */ | ||
90 | public function testSetEmptyKey() | ||
91 | { | ||
92 | $this->conf->set('', 'stuff'); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Set with an array key. | ||
97 | * | ||
98 | * @expectedException Exception | ||
99 | * @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*# | ||
100 | */ | ||
101 | public function testSetArrayKey() | ||
102 | { | ||
103 | $this->conf->set(array('foo' => 'bar'), 'stuff'); | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * Try to write the config without mandatory parameter (e.g. 'login'). | ||
108 | * | ||
109 | * @expectedException MissingFieldConfigException | ||
110 | */ | ||
111 | public function testWriteMissingParameter() | ||
112 | { | ||
113 | ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp'; | ||
114 | $this->assertFalse(file_exists($this->conf->getConfigFile())); | ||
115 | $this->conf->reload(); | ||
116 | |||
117 | $this->conf->write(true); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * Try to get non existent config keys. | ||
122 | */ | ||
123 | public function testGetNonExistent() | ||
124 | { | ||
125 | $this->assertEquals('', $this->conf->get('nope.test')); | ||
126 | $this->assertEquals('default', $this->conf->get('nope.test', 'default')); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * Test the 'exists' method with existent values. | ||
131 | */ | ||
132 | public function testExistsOk() | ||
133 | { | ||
134 | $this->assertTrue($this->conf->exists('login')); | ||
135 | $this->assertTrue($this->conf->exists('config.foo')); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * Test the 'exists' method with non existent or invalid values. | ||
140 | */ | ||
141 | public function testExistsKo() | ||
142 | { | ||
143 | $this->assertFalse($this->conf->exists('nope')); | ||
144 | $this->assertFalse($this->conf->exists('nope.nope')); | ||
145 | $this->assertFalse($this->conf->exists('')); | ||
146 | $this->assertFalse($this->conf->exists(false)); | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * Reset the ConfigManager instance. | ||
151 | */ | ||
152 | public function testReset() | ||
153 | { | ||
154 | $conf = $this->conf; | ||
155 | $this->assertTrue($conf === ConfigManager::getInstance()); | ||
156 | $this->assertFalse($conf === $this->conf->reset()); | ||
157 | $this->assertFalse($conf === ConfigManager::getInstance()); | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * Reload the config from file. | ||
162 | */ | ||
163 | public function testReload() | ||
164 | { | ||
165 | ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp'; | ||
166 | $newConf = ConfigJson::$PHP_HEADER . '{ "key": "value" }'; | ||
167 | file_put_contents($this->conf->getConfigFile(), $newConf); | ||
168 | $this->conf->reload(); | ||
169 | unlink($this->conf->getConfigFile()); | ||
170 | // Previous conf no longer exists, and new values have been loaded. | ||
171 | $this->assertFalse($this->conf->exists('login')); | ||
172 | $this->assertEquals('value', $this->conf->get('key')); | ||
173 | } | ||
174 | } | ||
diff --git a/tests/utils/config/configInvalid.json.php b/tests/utils/config/configInvalid.json.php new file mode 100644 index 00000000..c53e471d --- /dev/null +++ b/tests/utils/config/configInvalid.json.php | |||
@@ -0,0 +1,4 @@ | |||
1 | <?php /* | ||
2 | { | ||
3 | bad: bad, | ||
4 | } | ||
diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php new file mode 100644 index 00000000..71b59edd --- /dev/null +++ b/tests/utils/config/configJson.json.php | |||
@@ -0,0 +1,19 @@ | |||
1 | <?php /* | ||
2 | { | ||
3 | "redirector":"lala", | ||
4 | "login":"root", | ||
5 | "hash":"hash", | ||
6 | "salt":"salt", | ||
7 | "timezone":"Europe\/Paris", | ||
8 | "disablesessionprotection":false, | ||
9 | "privateLinkByDefault":true, | ||
10 | "title": "Shaarli", | ||
11 | "titleLink": "?", | ||
12 | "config": { | ||
13 | "foo": "bar", | ||
14 | "DATASTORE": "data\/datastore.php" | ||
15 | }, | ||
16 | "plugins": { | ||
17 | "WALLABAG_VERSION": 1 | ||
18 | } | ||
19 | } | ||
diff --git a/tests/utils/config/configUpdateDone.json.php b/tests/utils/config/configUpdateDone.json.php new file mode 100644 index 00000000..a4e460d1 --- /dev/null +++ b/tests/utils/config/configUpdateDone.json.php | |||
@@ -0,0 +1,4 @@ | |||
1 | <?php /* | ||
2 | { | ||
3 | "login": "root" | ||
4 | } | ||
diff --git a/tpl/linklist.html b/tpl/linklist.html index c0d42006..2316f145 100644 --- a/tpl/linklist.html +++ b/tpl/linklist.html | |||
@@ -88,7 +88,7 @@ | |||
88 | </span> | 88 | </span> |
89 | <br> | 89 | <br> |
90 | {if="$value.description"}<div class="linkdescription">{$value.description}</div>{/if} | 90 | {if="$value.description"}<div class="linkdescription">{$value.description}</div>{/if} |
91 | {if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"} | 91 | {if="!$hide_timestamps || isLoggedIn()"} |
92 | <span class="linkdate" title="Permalink"><a href="?{$value.linkdate|smallHash}">{function="strftime('%c', $value.timestamp)"} - permalink</a> - </span> | 92 | <span class="linkdate" title="Permalink"><a href="?{$value.linkdate|smallHash}">{function="strftime('%c', $value.timestamp)"} - permalink</a> - </span> |
93 | {else} | 93 | {else} |
94 | <span class="linkdate" title="Short link here"><a href="?{$value.shorturl}">permalink</a> - </span> | 94 | <span class="linkdate" title="Short link here"><a href="?{$value.shorturl}">permalink</a> - </span> |
diff --git a/tpl/tools.html b/tpl/tools.html index 78b81663..29ade725 100644 --- a/tpl/tools.html +++ b/tpl/tools.html | |||
@@ -9,7 +9,7 @@ | |||
9 | <br><br> | 9 | <br><br> |
10 | <a href="?do=pluginadmin"><b>Plugin administration</b><span>: Enable, disable and configure plugins.</span></a> | 10 | <a href="?do=pluginadmin"><b>Plugin administration</b><span>: Enable, disable and configure plugins.</span></a> |
11 | <br><br> | 11 | <br><br> |
12 | {if="!$GLOBALS['config']['OPEN_SHAARLI']"}<a href="?do=changepasswd"><b>Change password</b><span>: Change your password.</span></a> | 12 | {if="$openshaarli"}<a href="?do=changepasswd"><b>Change password</b><span>: Change your password.</span></a> |
13 | <br><br>{/if} | 13 | <br><br>{/if} |
14 | <a href="?do=changetag"><b>Rename/delete tags</b><span>: Rename or delete a tag in all links</span></a> | 14 | <a href="?do=changetag"><b>Rename/delete tags</b><span>: Rename or delete a tag in all links</span></a> |
15 | <br><br> | 15 | <br><br> |