ApiModuleManagerTest.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <?php
  2. /**
  3. * @covers ApiModuleManager
  4. *
  5. * @group API
  6. * @group Database
  7. * @group medium
  8. */
  9. class ApiModuleManagerTest extends MediaWikiTestCase {
  10. private function getModuleManager() {
  11. $request = new FauxRequest();
  12. $main = new ApiMain( $request );
  13. return new ApiModuleManager( $main );
  14. }
  15. public function newApiLogin( $main, $action ) {
  16. return new ApiLogin( $main, $action );
  17. }
  18. public function addModuleProvider() {
  19. return [
  20. 'plain class' => [
  21. 'login',
  22. 'action',
  23. ApiLogin::class,
  24. null,
  25. ],
  26. 'with factory' => [
  27. 'login',
  28. 'action',
  29. ApiLogin::class,
  30. [ $this, 'newApiLogin' ],
  31. ],
  32. 'with closure' => [
  33. 'logout',
  34. 'action',
  35. ApiLogout::class,
  36. function ( ApiMain $main, $action ) {
  37. return new ApiLogout( $main, $action );
  38. },
  39. ],
  40. ];
  41. }
  42. /**
  43. * @dataProvider addModuleProvider
  44. */
  45. public function testAddModule( $name, $group, $class, $factory = null ) {
  46. $moduleManager = $this->getModuleManager();
  47. $moduleManager->addModule( $name, $group, $class, $factory );
  48. $this->assertTrue( $moduleManager->isDefined( $name, $group ), 'isDefined' );
  49. $this->assertNotNull( $moduleManager->getModule( $name, $group, true ), 'getModule' );
  50. }
  51. public function addModulesProvider() {
  52. return [
  53. 'empty' => [
  54. [],
  55. 'action',
  56. ],
  57. 'simple' => [
  58. [
  59. 'login' => ApiLogin::class,
  60. 'logout' => ApiLogout::class,
  61. ],
  62. 'action',
  63. ],
  64. 'with factories' => [
  65. [
  66. 'login' => [
  67. 'class' => ApiLogin::class,
  68. 'factory' => [ $this, 'newApiLogin' ],
  69. ],
  70. 'logout' => [
  71. 'class' => ApiLogout::class,
  72. 'factory' => function ( ApiMain $main, $action ) {
  73. return new ApiLogout( $main, $action );
  74. },
  75. ],
  76. ],
  77. 'action',
  78. ],
  79. ];
  80. }
  81. /**
  82. * @dataProvider addModulesProvider
  83. */
  84. public function testAddModules( array $modules, $group ) {
  85. $moduleManager = $this->getModuleManager();
  86. $moduleManager->addModules( $modules, $group );
  87. foreach ( array_keys( $modules ) as $name ) {
  88. $this->assertTrue( $moduleManager->isDefined( $name, $group ), 'isDefined' );
  89. $this->assertNotNull( $moduleManager->getModule( $name, $group, true ), 'getModule' );
  90. }
  91. $this->assertTrue( true ); // Don't mark the test as risky if $modules is empty
  92. }
  93. public function getModuleProvider() {
  94. $modules = [
  95. 'feedrecentchanges' => ApiFeedRecentChanges::class,
  96. 'feedcontributions' => [ 'class' => ApiFeedContributions::class ],
  97. 'login' => [
  98. 'class' => ApiLogin::class,
  99. 'factory' => [ $this, 'newApiLogin' ],
  100. ],
  101. 'logout' => [
  102. 'class' => ApiLogout::class,
  103. 'factory' => function ( ApiMain $main, $action ) {
  104. return new ApiLogout( $main, $action );
  105. },
  106. ],
  107. ];
  108. return [
  109. 'legacy entry' => [
  110. $modules,
  111. 'feedrecentchanges',
  112. ApiFeedRecentChanges::class,
  113. ],
  114. 'just a class' => [
  115. $modules,
  116. 'feedcontributions',
  117. ApiFeedContributions::class,
  118. ],
  119. 'with factory' => [
  120. $modules,
  121. 'login',
  122. ApiLogin::class,
  123. ],
  124. 'with closure' => [
  125. $modules,
  126. 'logout',
  127. ApiLogout::class,
  128. ],
  129. ];
  130. }
  131. /**
  132. * @covers ApiModuleManager::getModule
  133. * @dataProvider getModuleProvider
  134. */
  135. public function testGetModule( $modules, $name, $expectedClass ) {
  136. $moduleManager = $this->getModuleManager();
  137. $moduleManager->addModules( $modules, 'test' );
  138. // should return the right module
  139. $module1 = $moduleManager->getModule( $name, null, false );
  140. $this->assertInstanceOf( $expectedClass, $module1 );
  141. // should pass group check (with caching disabled)
  142. $module2 = $moduleManager->getModule( $name, 'test', true );
  143. $this->assertNotNull( $module2 );
  144. // should use cached instance
  145. $module3 = $moduleManager->getModule( $name, null, false );
  146. $this->assertSame( $module1, $module3 );
  147. // should not use cached instance if caching is disabled
  148. $module4 = $moduleManager->getModule( $name, null, true );
  149. $this->assertNotSame( $module1, $module4 );
  150. }
  151. /**
  152. * @covers ApiModuleManager::getModule
  153. */
  154. public function testGetModule_null() {
  155. $modules = [
  156. 'login' => ApiLogin::class,
  157. 'logout' => ApiLogout::class,
  158. ];
  159. $moduleManager = $this->getModuleManager();
  160. $moduleManager->addModules( $modules, 'test' );
  161. $this->assertNull( $moduleManager->getModule( 'quux' ), 'unknown name' );
  162. $this->assertNull( $moduleManager->getModule( 'login', 'bla' ), 'wrong group' );
  163. }
  164. /**
  165. * @covers ApiModuleManager::getNames
  166. */
  167. public function testGetNames() {
  168. $fooModules = [
  169. 'login' => ApiLogin::class,
  170. 'logout' => ApiLogout::class,
  171. ];
  172. $barModules = [
  173. 'feedcontributions' => [ 'class' => ApiFeedContributions::class ],
  174. 'feedrecentchanges' => [ 'class' => ApiFeedRecentChanges::class ],
  175. ];
  176. $moduleManager = $this->getModuleManager();
  177. $moduleManager->addModules( $fooModules, 'foo' );
  178. $moduleManager->addModules( $barModules, 'bar' );
  179. $fooNames = $moduleManager->getNames( 'foo' );
  180. $this->assertArrayEquals( array_keys( $fooModules ), $fooNames );
  181. $allNames = $moduleManager->getNames();
  182. $allModules = array_merge( $fooModules, $barModules );
  183. $this->assertArrayEquals( array_keys( $allModules ), $allNames );
  184. }
  185. /**
  186. * @covers ApiModuleManager::getNamesWithClasses
  187. */
  188. public function testGetNamesWithClasses() {
  189. $fooModules = [
  190. 'login' => ApiLogin::class,
  191. 'logout' => ApiLogout::class,
  192. ];
  193. $barModules = [
  194. 'feedcontributions' => [ 'class' => ApiFeedContributions::class ],
  195. 'feedrecentchanges' => [ 'class' => ApiFeedRecentChanges::class ],
  196. ];
  197. $moduleManager = $this->getModuleManager();
  198. $moduleManager->addModules( $fooModules, 'foo' );
  199. $moduleManager->addModules( $barModules, 'bar' );
  200. $fooNamesWithClasses = $moduleManager->getNamesWithClasses( 'foo' );
  201. $this->assertArrayEquals( $fooModules, $fooNamesWithClasses );
  202. $allNamesWithClasses = $moduleManager->getNamesWithClasses();
  203. $allModules = array_merge( $fooModules, [
  204. 'feedcontributions' => ApiFeedContributions::class,
  205. 'feedrecentchanges' => ApiFeedRecentChanges::class,
  206. ] );
  207. $this->assertArrayEquals( $allModules, $allNamesWithClasses );
  208. }
  209. /**
  210. * @covers ApiModuleManager::getModuleGroup
  211. */
  212. public function testGetModuleGroup() {
  213. $fooModules = [
  214. 'login' => ApiLogin::class,
  215. 'logout' => ApiLogout::class,
  216. ];
  217. $barModules = [
  218. 'feedcontributions' => [ 'class' => ApiFeedContributions::class ],
  219. 'feedrecentchanges' => [ 'class' => ApiFeedRecentChanges::class ],
  220. ];
  221. $moduleManager = $this->getModuleManager();
  222. $moduleManager->addModules( $fooModules, 'foo' );
  223. $moduleManager->addModules( $barModules, 'bar' );
  224. $this->assertEquals( 'foo', $moduleManager->getModuleGroup( 'login' ) );
  225. $this->assertEquals( 'bar', $moduleManager->getModuleGroup( 'feedrecentchanges' ) );
  226. $this->assertNull( $moduleManager->getModuleGroup( 'quux' ) );
  227. }
  228. /**
  229. * @covers ApiModuleManager::getGroups
  230. */
  231. public function testGetGroups() {
  232. $fooModules = [
  233. 'login' => ApiLogin::class,
  234. 'logout' => ApiLogout::class,
  235. ];
  236. $barModules = [
  237. 'feedcontributions' => [ 'class' => ApiFeedContributions::class ],
  238. 'feedrecentchanges' => [ 'class' => ApiFeedRecentChanges::class ],
  239. ];
  240. $moduleManager = $this->getModuleManager();
  241. $moduleManager->addModules( $fooModules, 'foo' );
  242. $moduleManager->addModules( $barModules, 'bar' );
  243. $groups = $moduleManager->getGroups();
  244. $this->assertArrayEquals( [ 'foo', 'bar' ], $groups );
  245. }
  246. /**
  247. * @covers ApiModuleManager::getClassName
  248. */
  249. public function testGetClassName() {
  250. $fooModules = [
  251. 'login' => ApiLogin::class,
  252. 'logout' => ApiLogout::class,
  253. ];
  254. $barModules = [
  255. 'feedcontributions' => [ 'class' => ApiFeedContributions::class ],
  256. 'feedrecentchanges' => [ 'class' => ApiFeedRecentChanges::class ],
  257. ];
  258. $moduleManager = $this->getModuleManager();
  259. $moduleManager->addModules( $fooModules, 'foo' );
  260. $moduleManager->addModules( $barModules, 'bar' );
  261. $this->assertEquals(
  262. ApiLogin::class,
  263. $moduleManager->getClassName( 'login' )
  264. );
  265. $this->assertEquals(
  266. ApiLogout::class,
  267. $moduleManager->getClassName( 'logout' )
  268. );
  269. $this->assertEquals(
  270. ApiFeedContributions::class,
  271. $moduleManager->getClassName( 'feedcontributions' )
  272. );
  273. $this->assertEquals(
  274. ApiFeedRecentChanges::class,
  275. $moduleManager->getClassName( 'feedrecentchanges' )
  276. );
  277. $this->assertFalse(
  278. $moduleManager->getClassName( 'nonexistentmodule' )
  279. );
  280. }
  281. }