ActionTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. /**
  3. * @covers Action
  4. *
  5. * @group Action
  6. * @group Database
  7. *
  8. * @license GPL-2.0-or-later
  9. * @author Thiemo Kreuz
  10. */
  11. class ActionTest extends MediaWikiTestCase {
  12. protected function setUp() {
  13. parent::setUp();
  14. $context = $this->getContext();
  15. $this->setMwGlobals( 'wgActions', [
  16. 'null' => null,
  17. 'disabled' => false,
  18. 'view' => true,
  19. 'edit' => true,
  20. 'revisiondelete' => SpecialPageAction::class,
  21. 'dummy' => true,
  22. 'string' => 'NamedDummyAction',
  23. 'declared' => 'NonExistingClassName',
  24. 'callable' => [ $this, 'dummyActionCallback' ],
  25. 'object' => new InstantiatedDummyAction( $context->getWikiPage(), $context ),
  26. ] );
  27. }
  28. private function getPage() {
  29. return WikiPage::factory( Title::makeTitle( 0, 'Title' ) );
  30. }
  31. private function getContext( $requestedAction = null ) {
  32. $request = new FauxRequest( [ 'action' => $requestedAction ] );
  33. $context = new DerivativeContext( RequestContext::getMain() );
  34. $context->setRequest( $request );
  35. $context->setWikiPage( $this->getPage() );
  36. return $context;
  37. }
  38. public function actionProvider() {
  39. return [
  40. [ 'dummy', 'DummyAction' ],
  41. [ 'string', 'NamedDummyAction' ],
  42. [ 'callable', 'CalledDummyAction' ],
  43. [ 'object', 'InstantiatedDummyAction' ],
  44. // Capitalization is ignored
  45. [ 'DUMMY', 'DummyAction' ],
  46. [ 'STRING', 'NamedDummyAction' ],
  47. // Null and non-existing values
  48. [ 'null', null ],
  49. [ 'undeclared', null ],
  50. [ '', null ],
  51. [ false, null ],
  52. ];
  53. }
  54. /**
  55. * @dataProvider actionProvider
  56. * @param string $requestedAction
  57. * @param string|null $expected
  58. */
  59. public function testActionExists( $requestedAction, $expected ) {
  60. $exists = Action::exists( $requestedAction );
  61. $this->assertSame( $expected !== null, $exists );
  62. }
  63. public function testActionExists_doesNotRequireInstantiation() {
  64. // The method is not supposed to check if the action can be instantiated.
  65. $exists = Action::exists( 'declared' );
  66. $this->assertTrue( $exists );
  67. }
  68. /**
  69. * @dataProvider actionProvider
  70. * @param string $requestedAction
  71. * @param string|null $expected
  72. */
  73. public function testGetActionName( $requestedAction, $expected ) {
  74. $context = $this->getContext( $requestedAction );
  75. $actionName = Action::getActionName( $context );
  76. $this->assertEquals( $expected ?: 'nosuchaction', $actionName );
  77. }
  78. public function testGetActionName_editredlinkWorkaround() {
  79. // See https://phabricator.wikimedia.org/T22966
  80. $context = $this->getContext( 'editredlink' );
  81. $actionName = Action::getActionName( $context );
  82. $this->assertEquals( 'edit', $actionName );
  83. }
  84. public function testGetActionName_historysubmitWorkaround() {
  85. // See https://phabricator.wikimedia.org/T22966
  86. $context = $this->getContext( 'historysubmit' );
  87. $actionName = Action::getActionName( $context );
  88. $this->assertEquals( 'view', $actionName );
  89. }
  90. public function testGetActionName_revisiondeleteWorkaround() {
  91. // See https://phabricator.wikimedia.org/T22966
  92. $context = $this->getContext( 'historysubmit' );
  93. $context->getRequest()->setVal( 'revisiondelete', true );
  94. $actionName = Action::getActionName( $context );
  95. $this->assertEquals( 'revisiondelete', $actionName );
  96. }
  97. public function testGetActionName_whenCanNotUseWikiPage_defaultsToView() {
  98. $request = new FauxRequest( [ 'action' => 'edit' ] );
  99. $context = new DerivativeContext( RequestContext::getMain() );
  100. $context->setRequest( $request );
  101. $actionName = Action::getActionName( $context );
  102. $this->assertEquals( 'view', $actionName );
  103. }
  104. /**
  105. * @dataProvider actionProvider
  106. * @param string $requestedAction
  107. * @param string|null $expected
  108. */
  109. public function testActionFactory( $requestedAction, $expected ) {
  110. $context = $this->getContext();
  111. $action = Action::factory( $requestedAction, $context->getWikiPage(), $context );
  112. $this->assertType( $expected ?: 'null', $action );
  113. }
  114. public function testNull_doesNotExist() {
  115. $exists = Action::exists( null );
  116. $this->assertFalse( $exists );
  117. }
  118. public function testNull_defaultsToView() {
  119. $context = $this->getContext( null );
  120. $actionName = Action::getActionName( $context );
  121. $this->assertEquals( 'view', $actionName );
  122. }
  123. public function testNull_canNotBeInstantiated() {
  124. $page = $this->getPage();
  125. $action = Action::factory( null, $page );
  126. $this->assertNull( $action );
  127. }
  128. public function testDisabledAction_exists() {
  129. $exists = Action::exists( 'disabled' );
  130. $this->assertTrue( $exists );
  131. }
  132. public function testDisabledAction_isNotResolved() {
  133. $context = $this->getContext( 'disabled' );
  134. $actionName = Action::getActionName( $context );
  135. $this->assertEquals( 'nosuchaction', $actionName );
  136. }
  137. public function testDisabledAction_factoryReturnsFalse() {
  138. $page = $this->getPage();
  139. $action = Action::factory( 'disabled', $page );
  140. $this->assertFalse( $action );
  141. }
  142. public function dummyActionCallback() {
  143. $context = $this->getContext();
  144. return new CalledDummyAction( $context->getWikiPage(), $context );
  145. }
  146. }
  147. class DummyAction extends Action {
  148. public function getName() {
  149. return static::class;
  150. }
  151. public function show() {
  152. }
  153. public function execute() {
  154. }
  155. }
  156. class NamedDummyAction extends DummyAction {
  157. }
  158. class CalledDummyAction extends DummyAction {
  159. }
  160. class InstantiatedDummyAction extends DummyAction {
  161. }