Adds ConfigJson which handle the configuration in JSON format.

Also use the Updater to make the transition
This commit is contained in:
ArthurHoaro 2016-05-29 12:32:14 +02:00
parent 684e662a58
commit b74b96bfbd
13 changed files with 469 additions and 32 deletions

View file

@ -20,9 +20,9 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
protected static $testDatastore = 'sandbox/datastore.php';
/**
* @var string Config file path.
* @var string Config file path (without extension).
*/
protected static $configFile = 'tests/Updater/config.php';
protected static $configFile = 'tests/utils/config/configUpdater';
/**
* @var ConfigManager
@ -52,8 +52,9 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
)
);
ConfigManager::$CONFIG_FILE = 'tests/Updater/config';
$this->conf = ConfigManager::getInstance();
ConfigManager::$CONFIG_FILE = self::$configFile;
$this->conf = ConfigManager::reset();
$this->conf->reload();
foreach (self::$configFields as $key => $value) {
$this->conf->set($key, $value);
}
@ -67,8 +68,8 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
*/
public function tearDown()
{
if (is_file(self::$configFile)) {
unlink(self::$configFile);
if (is_file('tests/Updater/config.json')) {
unlink('tests/Updater/config.json');
}
if (is_file(self::$configFields['config']['DATADIR'] . '/options.php')) {
@ -214,6 +215,8 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
{
// Use writeConfig to create a options.php
ConfigManager::$CONFIG_FILE = 'tests/Updater/options';
$this->conf->setConfigIO(new ConfigPhp());
$invert = !$this->conf->get('privateLinkByDefault');
$this->conf->set('privateLinkByDefault', $invert);
$this->conf->write(true);
@ -225,12 +228,15 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
// merge configs
$updater = new Updater(array(), array(), true);
// This writes a new config file in tests/Updater/config.php
$updater->updateMethodMergeDeprecatedConfigFile();
// make sure updated field is changed
$this->conf->reload();
$this->assertEquals($invert, $this->conf->get('privateLinkByDefault'));
$this->assertFalse(is_file($optionsFile));
// Delete the generated file.
unlink($this->conf->getConfigFile());
}
/**
@ -257,4 +263,52 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
$updater->updateMethodRenameDashTags();
$this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude')));
}
/**
* Convert old PHP config file to JSON config.
*/
public function testConfigToJson()
{
$configFile = 'tests/utils/config/configPhp';
ConfigManager::$CONFIG_FILE = $configFile;
$conf = ConfigManager::reset();
// The ConfigIO is initialized with ConfigPhp.
$this->assertTrue($conf->getConfigIO() instanceof ConfigPhp);
$updater = new Updater(array(), array(), false);
$done = $updater->updateMethodConfigToJson();
$this->assertTrue($done);
// The ConfigIO has been updated to ConfigJson.
$this->assertTrue($conf->getConfigIO() instanceof ConfigJson);
$this->assertTrue(file_exists($conf->getConfigFile()));
// Check JSON config data.
$conf->reload();
$this->assertEquals('root', $conf->get('login'));
$this->assertEquals('lala', $conf->get('redirector'));
$this->assertEquals('data/datastore.php', $conf->get('config.DATASTORE'));
$this->assertEquals('1', $conf->get('plugins.WALLABAG_VERSION'));
rename($configFile . '.save.php', $configFile . '.php');
unlink($conf->getConfigFile());
}
/**
* Launch config conversion update with an existing JSON file => nothing to do.
*/
public function testConfigToJsonNothingToDo()
{
$configFile = 'tests/utils/config/configUpdateDone';
ConfigManager::$CONFIG_FILE = $configFile;
$conf = ConfigManager::reset();
$conf->reload();
$filetime = filemtime($conf->getConfigFile());
$updater = new Updater(array(), array(), false);
$done = $updater->updateMethodConfigToJson();
$this->assertTrue($done);
$expected = filemtime($conf->getConfigFile());
$this->assertEquals($expected, $filetime);
}
}

View file

@ -0,0 +1,125 @@
<?php
require_once 'application/config/ConfigJson.php';
/**
* Class ConfigJsonTest
*/
class ConfigJsonTest extends PHPUnit_Framework_TestCase
{
/**
* @var ConfigJson
*/
protected $configIO;
public function setUp()
{
$this->configIO = new ConfigJson();
}
/**
* Read a simple existing config file.
*/
public function testRead()
{
$conf = $this->configIO->read('tests/utils/config/configJson.json.php');
$this->assertEquals('root', $conf['login']);
$this->assertEquals('lala', $conf['redirector']);
$this->assertEquals('data/datastore.php', $conf['config']['DATASTORE']);
$this->assertEquals('1', $conf['plugins']['WALLABAG_VERSION']);
}
/**
* Read a non existent config file -> empty array.
*/
public function testReadNonExistent()
{
$this->assertEquals(array(), $this->configIO->read('nope'));
}
/**
* Read a non existent config file -> empty array.
*
* @expectedException Exception
* @expectedExceptionMessage An error occured while parsing JSON file: error code #4
*/
public function testReadInvalidJson()
{
$this->configIO->read('tests/utils/config/configInvalid.json.php');
}
/**
* Write a new config file.
*/
public function testWriteNew()
{
$dataFile = 'tests/utils/config/configWrite.json.php';
$data = array(
'login' => 'root',
'redirector' => 'lala',
'config' => array(
'DATASTORE' => 'data/datastore.php',
),
'plugins' => array(
'WALLABAG_VERSION' => '1',
)
);
$this->configIO->write($dataFile, $data);
// PHP 5.3 doesn't support json pretty print.
if (defined('JSON_PRETTY_PRINT')) {
$expected = '{
"login": "root",
"redirector": "lala",
"config": {
"DATASTORE": "data\/datastore.php"
},
"plugins": {
"WALLABAG_VERSION": "1"
}
}';
} else {
$expected = '{"login":"root","redirector":"lala","config":{"DATASTORE":"data\/datastore.php"},"plugins":{"WALLABAG_VERSION":"1"}}';
}
$expected = ConfigJson::$PHP_HEADER . $expected;
$this->assertEquals($expected, file_get_contents($dataFile));
unlink($dataFile);
}
/**
* Overwrite an existing setting.
*/
public function testOverwrite()
{
$source = 'tests/utils/config/configJson.json.php';
$dest = 'tests/utils/config/configOverwrite.json.php';
copy($source, $dest);
$conf = $this->configIO->read($dest);
$conf['redirector'] = 'blabla';
$this->configIO->write($dest, $conf);
$conf = $this->configIO->read($dest);
$this->assertEquals('blabla', $conf['redirector']);
unlink($dest);
}
/**
* Write to invalid path.
*
* @expectedException IOException
*/
public function testWriteInvalidArray()
{
$conf = array('conf' => 'value');
@$this->configIO->write(array(), $conf);
}
/**
* Write to invalid path.
*
* @expectedException IOException
*/
public function testWriteInvalidBlank()
{
$conf = array('conf' => 'value');
@$this->configIO->write('', $conf);
}
}

View file

@ -6,7 +6,7 @@
* Note: it only test the manager with ConfigJson,
* ConfigPhp is only a workaround to handle the transition to JSON type.
*/
class ConfigManagerTest extends \PHPUnit_Framework_TestCase
class ConfigManagerTest extends PHPUnit_Framework_TestCase
{
/**
* @var ConfigManager
@ -15,34 +15,160 @@ class ConfigManagerTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
ConfigManager::$CONFIG_FILE = 'tests/config/config';
$this->conf = ConfigManager::getInstance();
ConfigManager::$CONFIG_FILE = 'tests/utils/config/configJson';
$this->conf = ConfigManager::reset();
}
public function tearDown()
/**
* Simple config test:
* 1. Set settings.
* 2. Check settings value.
*/
public function testSetGet()
{
@unlink($this->conf->getConfigFile());
}
public function testSetWriteGet()
{
// This won't work with ConfigPhp.
$this->markTestIncomplete();
$this->conf->set('paramInt', 42);
$this->conf->set('paramString', 'value1');
$this->conf->set('paramBool', false);
$this->conf->set('paramArray', array('foo' => 'bar'));
$this->conf->set('paramNull', null);
$this->conf->write(true);
$this->conf->reload();
$this->assertEquals(42, $this->conf->get('paramInt'));
$this->assertEquals('value1', $this->conf->get('paramString'));
$this->assertFalse($this->conf->get('paramBool'));
$this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray'));
$this->assertEquals(null, $this->conf->get('paramNull'));
}
}
/**
* Set/write/get config test:
* 1. Set settings.
* 2. Write it to the config file.
* 3. Read the file.
* 4. Check settings value.
*/
public function testSetWriteGet()
{
$this->conf->set('paramInt', 42);
$this->conf->set('paramString', 'value1');
$this->conf->set('paramBool', false);
$this->conf->set('paramArray', array('foo' => 'bar'));
$this->conf->set('paramNull', null);
ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp';
$this->conf->write(true);
$this->conf->reload();
unlink($this->conf->getConfigFile());
$this->assertEquals(42, $this->conf->get('paramInt'));
$this->assertEquals('value1', $this->conf->get('paramString'));
$this->assertFalse($this->conf->get('paramBool'));
$this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray'));
$this->assertEquals(null, $this->conf->get('paramNull'));
}
/**
* Test set/write/get with nested keys.
*/
public function testSetWriteGetNested()
{
$this->conf->set('foo.bar.key.stuff', 'testSetWriteGetNested');
ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp';
$this->conf->write(true);
$this->conf->reload();
unlink($this->conf->getConfigFile());
$this->assertEquals('testSetWriteGetNested', $this->conf->get('foo.bar.key.stuff'));
}
/**
* Set with an empty key.
*
* @expectedException Exception
* @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*#
*/
public function testSetEmptyKey()
{
$this->conf->set('', 'stuff');
}
/**
* Set with an array key.
*
* @expectedException Exception
* @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*#
*/
public function testSetArrayKey()
{
$this->conf->set(array('foo' => 'bar'), 'stuff');
}
/**
* Try to write the config without mandatory parameter (e.g. 'login').
*
* @expectedException MissingFieldConfigException
*/
public function testWriteMissingParameter()
{
ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp';
$this->assertFalse(file_exists($this->conf->getConfigFile()));
$this->conf->reload();
$this->conf->write(true);
}
/**
* Try to get non existent config keys.
*/
public function testGetNonExistent()
{
$this->assertEquals('', $this->conf->get('nope.test'));
$this->assertEquals('default', $this->conf->get('nope.test', 'default'));
}
/**
* Test the 'exists' method with existent values.
*/
public function testExistsOk()
{
$this->assertTrue($this->conf->exists('login'));
$this->assertTrue($this->conf->exists('config.foo'));
}
/**
* Test the 'exists' method with non existent or invalid values.
*/
public function testExistsKo()
{
$this->assertFalse($this->conf->exists('nope'));
$this->assertFalse($this->conf->exists('nope.nope'));
$this->assertFalse($this->conf->exists(''));
$this->assertFalse($this->conf->exists(false));
}
/**
* Reset the ConfigManager instance.
*/
public function testReset()
{
$conf = $this->conf;
$this->assertTrue($conf === ConfigManager::getInstance());
$this->assertFalse($conf === $this->conf->reset());
$this->assertFalse($conf === ConfigManager::getInstance());
}
/**
* Reload the config from file.
*/
public function testReload()
{
ConfigManager::$CONFIG_FILE = 'tests/utils/config/configTmp';
$newConf = ConfigJson::$PHP_HEADER . '{ "key": "value" }';
file_put_contents($this->conf->getConfigFile(), $newConf);
$this->conf->reload();
unlink($this->conf->getConfigFile());
// Previous conf no longer exists, and new values have been loaded.
$this->assertFalse($this->conf->exists('login'));
$this->assertEquals('value', $this->conf->get('key'));
}
}

View file

@ -0,0 +1,4 @@
<?php /*
{
bad: bad,
}

View file

@ -0,0 +1,19 @@
<?php /*
{
"redirector":"lala",
"login":"root",
"hash":"hash",
"salt":"salt",
"timezone":"Europe\/Paris",
"disablesessionprotection":false,
"privateLinkByDefault":true,
"title": "Shaarli",
"titleLink": "?",
"config": {
"foo": "bar",
"DATASTORE": "data\/datastore.php"
},
"plugins": {
"WALLABAG_VERSION": 1
}
}

View file

@ -0,0 +1,4 @@
<?php /*
{
"login": "root"
}