3 namespace MediaWiki\Tests\Api\Validator
;
5 use MediaWiki\Api\ApiMain
;
6 use MediaWiki\Api\ApiModuleManager
;
7 use MediaWiki\Api\Validator\SubmoduleDef
;
8 use MediaWiki\Tests\Api\MockApi
;
9 use Wikimedia\Message\DataMessageValue
;
10 use Wikimedia\ParamValidator\ParamValidator
;
11 use Wikimedia\ParamValidator\SimpleCallbacks
;
12 use Wikimedia\ParamValidator\TypeDef\EnumDef
;
13 use Wikimedia\ParamValidator\ValidationException
;
14 use Wikimedia\TestingAccessWrapper
;
15 use Wikimedia\Tests\ParamValidator\TypeDef\TypeDefTestCase
;
18 * @covers \MediaWiki\Api\Validator\SubmoduleDef
20 class SubmoduleDefTest
extends TypeDefTestCase
{
22 protected function getInstance( SimpleCallbacks
$callbacks, array $options ) {
23 return new SubmoduleDef( $callbacks, $options );
26 private function mockApi() {
27 $api = $this->getMockBuilder( MockApi
::class )
28 ->onlyMethods( [ 'getModuleManager' ] )
30 $w = TestingAccessWrapper
::newFromObject( $api );
31 $w->mModuleName
= 'testmod';
32 $w->mMainModule
= new ApiMain
;
33 $w->mModulePrefix
= 'tt';
35 $w->mMainModule
->getModuleManager()->addModule( 'testmod', 'action', [
36 'class' => MockApi
::class,
37 'factory' => static function () use ( $api ) {
42 $dep = $this->getMockBuilder( MockApi
::class )
43 ->onlyMethods( [ 'isDeprecated' ] )
45 $dep->method( 'isDeprecated' )->willReturn( true );
46 $int = $this->getMockBuilder( MockApi
::class )
47 ->onlyMethods( [ 'isInternal' ] )
49 $int->method( 'isInternal' )->willReturn( true );
50 $depint = $this->getMockBuilder( MockApi
::class )
51 ->onlyMethods( [ 'isDeprecated', 'isInternal' ] )
53 $depint->method( 'isDeprecated' )->willReturn( true );
54 $depint->method( 'isInternal' )->willReturn( true );
56 $manager = new ApiModuleManager( $api );
57 $api->method( 'getModuleManager' )->willReturn( $manager );
58 $manager->addModule( 'mod1', 'test', MockApi
::class );
59 $manager->addModule( 'mod2', 'test', MockApi
::class );
60 $manager->addModule( 'dep', 'test', [
61 'class' => MockApi
::class,
62 'factory' => static function () use ( $dep ) {
66 $manager->addModule( 'depint', 'test', [
67 'class' => MockApi
::class,
68 'factory' => static function () use ( $depint ) {
72 $manager->addModule( 'int', 'test', [
73 'class' => MockApi
::class,
74 'factory' => static function () use ( $int ) {
78 $manager->addModule( 'recurse', 'test', [
79 'class' => MockApi
::class,
80 'factory' => static function () use ( $api ) {
84 $manager->addModule( 'mod3', 'xyz', MockApi
::class );
86 $this->assertSame( $api, $api->getModuleFromPath( 'testmod' ) );
87 $this->assertSame( $dep, $api->getModuleFromPath( 'testmod+dep' ) );
88 $this->assertSame( $int, $api->getModuleFromPath( 'testmod+int' ) );
89 $this->assertSame( $depint, $api->getModuleFromPath( 'testmod+depint' ) );
94 public function provideValidate() {
96 'module' => $this->mockApi(),
99 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> [
100 'mod2' => 'testmod+mod1',
101 'mod3' => 'testmod+mod3',
106 'Basic' => [ 'mod1', 'mod1', [], $opts ],
107 'Nonexistent submodule' => [
109 new ValidationException(
110 DataMessageValue
::new( 'paramvalidator-badvalue', [], 'badvalue', [] ), 'test', 'mod3', []
115 'Mapped' => [ 'mod3', 'mod3', $map, $opts ],
116 'Mapped, not in map' => [
118 new ValidationException(
119 DataMessageValue
::new( 'paramvalidator-badvalue', [], 'badvalue', [] ), 'test', 'mod1', $map
127 public function provideCheckSettings() {
129 'module' => $this->mockApi(),
132 'Y', EnumDef
::PARAM_DEPRECATED_VALUES
,
133 SubmoduleDef
::PARAM_SUBMODULE_MAP
, SubmoduleDef
::PARAM_SUBMODULE_PARAM_PREFIX
142 'allowedKeys' => $keys,
147 'Test with everything' => [
149 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> [
150 'foo' => 'testmod+mod1', 'bar' => 'testmod+mod2'
152 SubmoduleDef
::PARAM_SUBMODULE_PARAM_PREFIX
=> 'g',
157 'allowedKeys' => $keys,
164 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> false,
165 SubmoduleDef
::PARAM_SUBMODULE_PARAM_PREFIX
=> true,
171 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> 'PARAM_SUBMODULE_MAP must be an array, got boolean',
172 SubmoduleDef
::PARAM_SUBMODULE_PARAM_PREFIX
173 => 'PARAM_SUBMODULE_PARAM_PREFIX must be a string, got boolean',
175 'allowedKeys' => $keys,
180 'Bad values in map' => [
182 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> [
183 'a' => 'testmod+mod1',
186 'd' => 'testmod+mod7',
187 'r' => 'testmod+recurse+recurse',
194 'Values for PARAM_SUBMODULE_MAP must be strings, but value for "b" is boolean',
195 'Values for PARAM_SUBMODULE_MAP must be strings, but value for "c" is NULL',
196 'PARAM_SUBMODULE_MAP contains "testmod+mod7", which is not a valid module path',
198 'allowedKeys' => $keys,
206 public function provideGetEnumValues() {
208 'module' => $this->mockApi(),
213 [ ParamValidator
::PARAM_TYPE
=> 'submodule' ],
214 [ 'mod1', 'mod2', 'dep', 'depint', 'int', 'recurse' ],
219 ParamValidator
::PARAM_TYPE
=> 'submodule',
220 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> [
221 'mod2' => 'test+mod1',
222 'mod3' => 'test+mod3',
231 public function provideGetInfo() {
233 'module' => $this->mockApi(),
240 'type' => [ 'mod1', 'mod2', 'recurse', 'dep', 'int', 'depint' ],
242 'mod1' => 'testmod+mod1',
243 'mod2' => 'testmod+mod2',
244 'recurse' => 'testmod+recurse',
245 'dep' => 'testmod+dep',
246 'int' => 'testmod+int',
247 'depint' => 'testmod+depint',
249 'deprecatedvalues' => [ 'dep', 'depint' ],
250 'internalvalues' => [ 'depint', 'int' ],
253 ParamValidator
::PARAM_TYPE
=> '<message key="paramvalidator-help-type-enum"><text>1</text><list listType="comma"><text>[[Special:ApiHelp/testmod+mod1|<span dir="ltr" lang="en">mod1</span>]]</text><text>[[Special:ApiHelp/testmod+mod2|<span dir="ltr" lang="en">mod2</span>]]</text><text>[[Special:ApiHelp/testmod+recurse|<span dir="ltr" lang="en">recurse</span>]]</text><text>[[Special:ApiHelp/testmod+dep|<span dir="ltr" lang="en" class="apihelp-deprecated-value">dep</span>]]</text><text>[[Special:ApiHelp/testmod+int|<span dir="ltr" lang="en" class="apihelp-internal-value">int</span>]]</text><text>[[Special:ApiHelp/testmod+depint|<span dir="ltr" lang="en" class="apihelp-deprecated-value apihelp-internal-value">depint</span>]]</text></list><num>6</num></message>',
254 ParamValidator
::PARAM_ISMULTI
=> null,
260 ParamValidator
::PARAM_DEFAULT
=> 'mod3|mod4',
261 ParamValidator
::PARAM_ISMULTI
=> true,
262 SubmoduleDef
::PARAM_SUBMODULE_PARAM_PREFIX
=> 'g',
263 SubmoduleDef
::PARAM_SUBMODULE_MAP
=> [
264 'xyz' => 'testmod+dep',
265 'mod3' => 'testmod+mod3',
266 'mod4' => 'testmod+mod4', // doesn't exist
270 'type' => [ 'mod3', 'mod4', 'xyz' ],
272 'mod3' => 'testmod+mod3',
273 'mod4' => 'testmod+mod4',
274 'xyz' => 'testmod+dep',
276 'submoduleparamprefix' => 'g',
277 'deprecatedvalues' => [ 'xyz' ],
280 ParamValidator
::PARAM_TYPE
=> '<message key="paramvalidator-help-type-enum"><text>2</text><list listType="comma"><text>[[Special:ApiHelp/testmod+mod3|<span dir="ltr" lang="en">mod3</span>]]</text><text>[[Special:ApiHelp/testmod+mod4|<span dir="ltr" lang="en">mod4</span>]]</text><text>[[Special:ApiHelp/testmod+dep|<span dir="ltr" lang="en" class="apihelp-deprecated-value">xyz</span>]]</text></list><num>3</num></message>',
281 ParamValidator
::PARAM_ISMULTI
=> null,