2021-11-09 17:29:14 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace phpunit\unit\includes\Settings;
|
|
|
|
|
|
|
|
|
|
use MediaWiki\Settings\Config\ArrayConfigBuilder;
|
|
|
|
|
use MediaWiki\Settings\Config\ConfigSink;
|
2021-11-12 19:56:33 +00:00
|
|
|
use MediaWiki\Settings\Config\MergeStrategy;
|
2021-11-24 16:20:29 +00:00
|
|
|
use MediaWiki\Settings\Config\PhpIniSink;
|
2021-11-09 17:29:14 +00:00
|
|
|
use MediaWiki\Settings\SettingsBuilder;
|
|
|
|
|
use MediaWiki\Settings\SettingsBuilderException;
|
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Settings\SettingsBuilder
|
|
|
|
|
*/
|
|
|
|
|
class SettingsBuilderTest extends TestCase {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param ConfigSink|null $configBuilder
|
2021-11-24 16:20:29 +00:00
|
|
|
* @param PhpIniSink|null $phpIniSink
|
2021-11-09 17:29:14 +00:00
|
|
|
* @return SettingsBuilder
|
|
|
|
|
*/
|
2021-11-24 16:20:29 +00:00
|
|
|
private function newSettingsBuilder(
|
|
|
|
|
ConfigSink $configBuilder = null,
|
|
|
|
|
PhpIniSink $phpIniSink = null
|
|
|
|
|
): SettingsBuilder {
|
2021-11-09 17:29:14 +00:00
|
|
|
return new SettingsBuilder(
|
|
|
|
|
__DIR__,
|
2021-11-24 16:20:29 +00:00
|
|
|
$configBuilder ?? new ArrayConfigBuilder(),
|
|
|
|
|
$phpIniSink ?? new PhpIniSink()
|
2021-11-09 17:29:14 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testLoadingFromFile() {
|
|
|
|
|
$configBuilder = new ArrayConfigBuilder();
|
2021-11-24 16:20:29 +00:00
|
|
|
|
|
|
|
|
$phpIniSinkMock = $this->createMock( PhpIniSink::class );
|
|
|
|
|
$phpIniSinkMock->expects( $this->once() )->method( 'set' )->with( 'foo', 'bar' );
|
|
|
|
|
|
|
|
|
|
$setting = $this->newSettingsBuilder( $configBuilder, $phpIniSinkMock );
|
2021-11-09 17:29:14 +00:00
|
|
|
$setting->loadFile( 'fixtures/settings.json' )->apply();
|
|
|
|
|
|
|
|
|
|
$config = $configBuilder->build();
|
|
|
|
|
$this->assertSame( 'TEST', $config->get( 'Something' ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function provideConfigOverrides() {
|
|
|
|
|
yield 'sets a value from a single settings file' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[ 'config' => [ 'MySetting' => 'MyValue', ], ],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => 'MyValue',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'merges different values from multiple settings files' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[ 'config' => [ 'MySetting' => 'MyValue', ], ],
|
|
|
|
|
[ 'config' => [ 'MyOtherSetting' => 'MyOtherValue', ], ],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => 'MyValue',
|
|
|
|
|
'MyOtherSetting' => 'MyOtherValue',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'overrides value in config' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[ 'config' => [ 'MySetting' => 'MyValue', ], ],
|
|
|
|
|
[ 'config' => [ 'MySetting' => 'MyOtherValue', ], ],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => 'MyOtherValue',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'sets a default from schema' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[ 'config-schema' => [ 'MySetting' => [ 'default' => 'MyDefault', ], ], ],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => 'MyDefault',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'value in config overrides default from schema' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[
|
|
|
|
|
'config-schema' => [ 'MySetting' => [ 'default' => 'MyDefault', ], ],
|
|
|
|
|
'config' => [ 'MySetting' => 'MyValue', ],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => 'MyValue',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'default null is applied' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[ 'config-schema' => [ 'MySetting' => [ 'default' => null, ], ], ],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => null,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'null value can override default' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[
|
|
|
|
|
'config-schema' => [ 'MySetting' => [ 'default' => 'default', ], ],
|
|
|
|
|
'config' => [ 'MySetting' => null, ],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => null,
|
|
|
|
|
],
|
|
|
|
|
];
|
2021-11-12 19:56:33 +00:00
|
|
|
yield 'merge strategy is applied when setting config' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[
|
|
|
|
|
'config-schema' => [ 'MySetting' => [
|
|
|
|
|
'mergeStrategy' => MergeStrategy::ARRAY_MERGE_RECURSIVE
|
|
|
|
|
], ],
|
|
|
|
|
'config' => [ 'MySetting' => [ 'a' => [ 'b' => 'c' ], ], ],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'config' => [ 'MySetting' => [ 'a' => [ 'b' => 'd' ], ], ],
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => [ 'a' => [ 'b' => [ 'c', 'd' ], ], ],
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'merge strategy is applied backwards setting schema default' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[
|
|
|
|
|
'config' => [ 'MySetting' => [ 'a' => [ 'b' => 'd' ], ], ],
|
|
|
|
|
'config-schema' => [ 'MySetting' => [
|
|
|
|
|
'mergeStrategy' => MergeStrategy::ARRAY_MERGE_RECURSIVE,
|
|
|
|
|
'default' => [ 'a' => [ 'b' => 'c' ], ],
|
|
|
|
|
], ],
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => [ 'a' => [ 'b' => [ 'c', 'd' ], ], ],
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
yield 'merge strategy is applied backwards setting schema default in different batch' => [
|
|
|
|
|
'settingsBatches' => [
|
|
|
|
|
[
|
|
|
|
|
'config' => [ 'MySetting' => [ 'a' => [ 'b' => 'd' ], ], ],
|
|
|
|
|
], [
|
|
|
|
|
'config-schema' => [ 'MySetting' => [
|
|
|
|
|
'mergeStrategy' => MergeStrategy::ARRAY_MERGE_RECURSIVE,
|
|
|
|
|
'default' => [ 'a' => [ 'b' => 'c' ], ],
|
|
|
|
|
], ],
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expectedGlobals' => [
|
|
|
|
|
'MySetting' => [ 'a' => [ 'b' => [ 'c', 'd' ], ], ],
|
|
|
|
|
],
|
|
|
|
|
];
|
2021-11-09 17:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideConfigOverrides
|
|
|
|
|
*/
|
|
|
|
|
public function testConfigOverrides( array $settingsBatches, array $expectedGlobals ) {
|
|
|
|
|
$configBuilder = new ArrayConfigBuilder();
|
|
|
|
|
$setting = $this->newSettingsBuilder( $configBuilder );
|
|
|
|
|
foreach ( $settingsBatches as $batch ) {
|
|
|
|
|
$setting->loadArray( $batch );
|
|
|
|
|
}
|
|
|
|
|
$setting->apply();
|
2021-11-11 17:50:14 +00:00
|
|
|
foreach ( $expectedGlobals as $key => $value ) {
|
|
|
|
|
$this->assertSame( $value, $configBuilder->build()->get( $key ) );
|
|
|
|
|
}
|
2021-11-09 17:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testApplyPurgesState() {
|
|
|
|
|
$configBuilder = new ArrayConfigBuilder();
|
|
|
|
|
$setting = $this->newSettingsBuilder( $configBuilder );
|
2021-11-11 17:50:14 +00:00
|
|
|
$setting->loadArray( [ 'config' => [ 'MySetting' => 'MyValue', ], ] )
|
|
|
|
|
->apply();
|
|
|
|
|
$this->assertSame( 'MyValue', $configBuilder->build()->get( 'MySetting' ) );
|
2021-11-09 17:29:14 +00:00
|
|
|
$configBuilder->set( 'MySetting', 'MyOtherValue' );
|
|
|
|
|
// Calling apply a second time should not redefine the global
|
|
|
|
|
// since the state should be cleared
|
|
|
|
|
$setting->apply();
|
2021-11-11 17:50:14 +00:00
|
|
|
$this->assertSame( 'MyOtherValue', $configBuilder->build()->get( 'MySetting' ) );
|
2021-11-09 17:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testApplyDefaultDoesNotOverwriteExisting() {
|
2021-11-11 17:50:14 +00:00
|
|
|
$configBuilder = ( new ArrayConfigBuilder() )
|
|
|
|
|
->set( 'MySetting', 'existing' );
|
2021-11-09 17:29:14 +00:00
|
|
|
$this->newSettingsBuilder( $configBuilder )
|
|
|
|
|
->loadArray( [ 'config-schema' => [ 'MySetting' => [ 'default' => 'default' ], ], ] )
|
|
|
|
|
->apply();
|
2021-11-11 17:50:14 +00:00
|
|
|
$this->assertSame( 'existing', $configBuilder->build()->get( 'MySetting' ) );
|
2021-11-09 17:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testConfigSchemaOverrideNotAllowed() {
|
|
|
|
|
$this->expectException( SettingsBuilderException::class );
|
|
|
|
|
$this->newSettingsBuilder()
|
|
|
|
|
->loadArray( [ 'config-schema' => [ 'MySetting' => [ 'default' => 'default' ], ], ] )
|
|
|
|
|
->loadArray( [ 'config-schema' => [ 'MySetting' => [ 'default' => 'override' ], ], ] )
|
|
|
|
|
->apply();
|
|
|
|
|
}
|
|
|
|
|
}
|