ApiContinuationManagerTest.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. /**
  3. * @covers ApiContinuationManager
  4. * @group API
  5. */
  6. class ApiContinuationManagerTest extends MediaWikiTestCase {
  7. private static function getManager( $continue, $allModules, $generatedModules ) {
  8. $context = new DerivativeContext( RequestContext::getMain() );
  9. $context->setRequest( new FauxRequest( [ 'continue' => $continue ] ) );
  10. $main = new ApiMain( $context );
  11. return new ApiContinuationManager( $main, $allModules, $generatedModules );
  12. }
  13. public function testContinuation() {
  14. $allModules = [
  15. new MockApiQueryBase( 'mock1' ),
  16. new MockApiQueryBase( 'mock2' ),
  17. new MockApiQueryBase( 'mocklist' ),
  18. ];
  19. $generator = new MockApiQueryBase( 'generator' );
  20. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  21. $this->assertSame( ApiMain::class, $manager->getSource() );
  22. $this->assertSame( false, $manager->isGeneratorDone() );
  23. $this->assertSame( $allModules, $manager->getRunModules() );
  24. $manager->addContinueParam( $allModules[0], 'm1continue', [ 1, 2 ] );
  25. $manager->addContinueParam( $allModules[2], 'mlcontinue', 2 );
  26. $manager->addGeneratorContinueParam( $generator, 'gcontinue', 3 );
  27. $this->assertSame( [ [
  28. 'mlcontinue' => 2,
  29. 'm1continue' => '1|2',
  30. 'continue' => '||mock2',
  31. ], false ], $manager->getContinuation() );
  32. $this->assertSame( [
  33. 'mock1' => [ 'm1continue' => '1|2' ],
  34. 'mocklist' => [ 'mlcontinue' => 2 ],
  35. 'generator' => [ 'gcontinue' => 3 ],
  36. ], $manager->getRawContinuation() );
  37. $result = new ApiResult( 0 );
  38. $manager->setContinuationIntoResult( $result );
  39. $this->assertSame( [
  40. 'mlcontinue' => 2,
  41. 'm1continue' => '1|2',
  42. 'continue' => '||mock2',
  43. ], $result->getResultData( 'continue' ) );
  44. $this->assertSame( null, $result->getResultData( 'batchcomplete' ) );
  45. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  46. $this->assertSame( false, $manager->isGeneratorDone() );
  47. $this->assertSame( $allModules, $manager->getRunModules() );
  48. $manager->addContinueParam( $allModules[0], 'm1continue', [ 1, 2 ] );
  49. $manager->addGeneratorContinueParam( $generator, 'gcontinue', [ 3, 4 ] );
  50. $this->assertSame( [ [
  51. 'm1continue' => '1|2',
  52. 'continue' => '||mock2|mocklist',
  53. ], false ], $manager->getContinuation() );
  54. $this->assertSame( [
  55. 'mock1' => [ 'm1continue' => '1|2' ],
  56. 'generator' => [ 'gcontinue' => '3|4' ],
  57. ], $manager->getRawContinuation() );
  58. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  59. $this->assertSame( false, $manager->isGeneratorDone() );
  60. $this->assertSame( $allModules, $manager->getRunModules() );
  61. $manager->addContinueParam( $allModules[2], 'mlcontinue', 2 );
  62. $manager->addGeneratorContinueParam( $generator, 'gcontinue', 3 );
  63. $this->assertSame( [ [
  64. 'mlcontinue' => 2,
  65. 'gcontinue' => 3,
  66. 'continue' => 'gcontinue||',
  67. ], true ], $manager->getContinuation() );
  68. $this->assertSame( [
  69. 'mocklist' => [ 'mlcontinue' => 2 ],
  70. 'generator' => [ 'gcontinue' => 3 ],
  71. ], $manager->getRawContinuation() );
  72. $result = new ApiResult( 0 );
  73. $manager->setContinuationIntoResult( $result );
  74. $this->assertSame( [
  75. 'mlcontinue' => 2,
  76. 'gcontinue' => 3,
  77. 'continue' => 'gcontinue||',
  78. ], $result->getResultData( 'continue' ) );
  79. $this->assertSame( true, $result->getResultData( 'batchcomplete' ) );
  80. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  81. $this->assertSame( false, $manager->isGeneratorDone() );
  82. $this->assertSame( $allModules, $manager->getRunModules() );
  83. $manager->addGeneratorContinueParam( $generator, 'gcontinue', 3 );
  84. $this->assertSame( [ [
  85. 'gcontinue' => 3,
  86. 'continue' => 'gcontinue||mocklist',
  87. ], true ], $manager->getContinuation() );
  88. $this->assertSame( [
  89. 'generator' => [ 'gcontinue' => 3 ],
  90. ], $manager->getRawContinuation() );
  91. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  92. $this->assertSame( false, $manager->isGeneratorDone() );
  93. $this->assertSame( $allModules, $manager->getRunModules() );
  94. $manager->addContinueParam( $allModules[0], 'm1continue', [ 1, 2 ] );
  95. $manager->addContinueParam( $allModules[2], 'mlcontinue', 2 );
  96. $this->assertSame( [ [
  97. 'mlcontinue' => 2,
  98. 'm1continue' => '1|2',
  99. 'continue' => '||mock2',
  100. ], false ], $manager->getContinuation() );
  101. $this->assertSame( [
  102. 'mock1' => [ 'm1continue' => '1|2' ],
  103. 'mocklist' => [ 'mlcontinue' => 2 ],
  104. ], $manager->getRawContinuation() );
  105. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  106. $this->assertSame( false, $manager->isGeneratorDone() );
  107. $this->assertSame( $allModules, $manager->getRunModules() );
  108. $manager->addContinueParam( $allModules[0], 'm1continue', [ 1, 2 ] );
  109. $this->assertSame( [ [
  110. 'm1continue' => '1|2',
  111. 'continue' => '||mock2|mocklist',
  112. ], false ], $manager->getContinuation() );
  113. $this->assertSame( [
  114. 'mock1' => [ 'm1continue' => '1|2' ],
  115. ], $manager->getRawContinuation() );
  116. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  117. $this->assertSame( false, $manager->isGeneratorDone() );
  118. $this->assertSame( $allModules, $manager->getRunModules() );
  119. $manager->addContinueParam( $allModules[2], 'mlcontinue', 2 );
  120. $this->assertSame( [ [
  121. 'mlcontinue' => 2,
  122. 'continue' => '-||mock1|mock2',
  123. ], true ], $manager->getContinuation() );
  124. $this->assertSame( [
  125. 'mocklist' => [ 'mlcontinue' => 2 ],
  126. ], $manager->getRawContinuation() );
  127. $manager = self::getManager( '', $allModules, [ 'mock1', 'mock2' ] );
  128. $this->assertSame( false, $manager->isGeneratorDone() );
  129. $this->assertSame( $allModules, $manager->getRunModules() );
  130. $this->assertSame( [ [], true ], $manager->getContinuation() );
  131. $this->assertSame( [], $manager->getRawContinuation() );
  132. $manager = self::getManager( '||mock2', $allModules, [ 'mock1', 'mock2' ] );
  133. $this->assertSame( false, $manager->isGeneratorDone() );
  134. $this->assertSame(
  135. array_values( array_diff_key( $allModules, [ 1 => 1 ] ) ),
  136. $manager->getRunModules()
  137. );
  138. $manager = self::getManager( '-||', $allModules, [ 'mock1', 'mock2' ] );
  139. $this->assertSame( true, $manager->isGeneratorDone() );
  140. $this->assertSame(
  141. array_values( array_diff_key( $allModules, [ 0 => 0, 1 => 1 ] ) ),
  142. $manager->getRunModules()
  143. );
  144. try {
  145. self::getManager( 'foo', $allModules, [ 'mock1', 'mock2' ] );
  146. $this->fail( 'Expected exception not thrown' );
  147. } catch ( ApiUsageException $ex ) {
  148. $this->assertTrue( ApiTestCase::apiExceptionHasCode( $ex, 'badcontinue' ),
  149. 'Expected exception'
  150. );
  151. }
  152. $manager = self::getManager(
  153. '||mock2',
  154. array_slice( $allModules, 0, 2 ),
  155. [ 'mock1', 'mock2' ]
  156. );
  157. try {
  158. $manager->addContinueParam( $allModules[1], 'm2continue', 1 );
  159. $this->fail( 'Expected exception not thrown' );
  160. } catch ( UnexpectedValueException $ex ) {
  161. $this->assertSame(
  162. 'Module \'mock2\' was not supposed to have been executed, ' .
  163. 'but it was executed anyway',
  164. $ex->getMessage(),
  165. 'Expected exception'
  166. );
  167. }
  168. try {
  169. $manager->addContinueParam( $allModules[2], 'mlcontinue', 1 );
  170. $this->fail( 'Expected exception not thrown' );
  171. } catch ( UnexpectedValueException $ex ) {
  172. $this->assertSame(
  173. 'Module \'mocklist\' called ApiContinuationManager::addContinueParam ' .
  174. 'but was not passed to ApiContinuationManager::__construct',
  175. $ex->getMessage(),
  176. 'Expected exception'
  177. );
  178. }
  179. }
  180. }