Make an empty "?action=" parameter default to "view"
[lhc/web/wiklou.git] / tests / phpunit / includes / actions / ActionTest.php
1 <?php
2
3 /**
4 * @covers Action
5 *
6 * @author Thiemo Mättig
7 *
8 * @group Action
9 * @group Database
10 */
11 class ActionTest extends MediaWikiTestCase {
12
13 protected function setUp() {
14 parent::setUp();
15
16 $context = $this->getContext();
17 $this->setMwGlobals( 'wgActions', [
18 'null' => null,
19 'disabled' => false,
20 'view' => true,
21 'edit' => true,
22 'revisiondelete' => 'SpecialPageAction',
23 'dummy' => true,
24 'string' => 'NamedDummyAction',
25 'declared' => 'NonExistingClassName',
26 'callable' => [ $this, 'dummyActionCallback' ],
27 'object' => new InstantiatedDummyAction( $context->getWikiPage(), $context ),
28 ] );
29 }
30
31 private function getPage() {
32 return WikiPage::factory( Title::makeTitle( 0, 'Title' ) );
33 }
34
35 private function getContext( $requestedAction = null ) {
36 $request = new FauxRequest( [ 'action' => $requestedAction ] );
37
38 $context = new DerivativeContext( RequestContext::getMain() );
39 $context->setRequest( $request );
40 $context->setWikiPage( $this->getPage() );
41
42 return $context;
43 }
44
45 public function actionProvider() {
46 return [
47 [ 'dummy', 'DummyAction' ],
48 [ 'string', 'NamedDummyAction' ],
49 [ 'callable', 'CalledDummyAction' ],
50 [ 'object', 'InstantiatedDummyAction' ],
51
52 // Capitalization is ignored
53 [ 'DUMMY', 'DummyAction' ],
54 [ 'STRING', 'NamedDummyAction' ],
55
56 // Null and non-existing values
57 [ 'null', null ],
58 [ 'undeclared', null ],
59 ];
60 }
61
62 /**
63 * @dataProvider actionProvider
64 * @param string $requestedAction
65 * @param string|null $expected
66 */
67 public function testActionExists( $requestedAction, $expected ) {
68 $exists = Action::exists( $requestedAction );
69
70 $this->assertSame( $expected !== null, $exists );
71 }
72
73 public function testActionExists_doesNotRequireInstantiation() {
74 // The method is not supposed to check if the action can be instantiated.
75 $exists = Action::exists( 'declared' );
76
77 $this->assertTrue( $exists );
78 }
79
80 /**
81 * @dataProvider actionProvider
82 * @param string $requestedAction
83 * @param string|null $expected
84 */
85 public function testGetActionName( $requestedAction, $expected ) {
86 $context = $this->getContext( $requestedAction );
87 $actionName = Action::getActionName( $context );
88
89 $this->assertEquals( $expected ?: 'nosuchaction', $actionName );
90 }
91
92 public function testGetActionName_editredlinkWorkaround() {
93 // See https://phabricator.wikimedia.org/T22966
94 $context = $this->getContext( 'editredlink' );
95 $actionName = Action::getActionName( $context );
96
97 $this->assertEquals( 'edit', $actionName );
98 }
99
100 public function testGetActionName_historysubmitWorkaround() {
101 // See https://phabricator.wikimedia.org/T22966
102 $context = $this->getContext( 'historysubmit' );
103 $actionName = Action::getActionName( $context );
104
105 $this->assertEquals( 'view', $actionName );
106 }
107
108 public function testGetActionName_revisiondeleteWorkaround() {
109 // See https://phabricator.wikimedia.org/T22966
110 $context = $this->getContext( 'historysubmit' );
111 $context->getRequest()->setVal( 'revisiondelete', true );
112 $actionName = Action::getActionName( $context );
113
114 $this->assertEquals( 'revisiondelete', $actionName );
115 }
116
117 public function testGetActionName_whenCanNotUseWikiPage_defaultsToView() {
118 $request = new FauxRequest( [ 'action' => 'edit' ] );
119 $context = new DerivativeContext( RequestContext::getMain() );
120 $context->setRequest( $request );
121 $actionName = Action::getActionName( $context );
122
123 $this->assertEquals( 'view', $actionName );
124 }
125
126 /**
127 * @dataProvider actionProvider
128 * @param string $requestedAction
129 * @param string|null $expected
130 */
131 public function testActionFactory( $requestedAction, $expected ) {
132 $context = $this->getContext();
133 $action = Action::factory( $requestedAction, $context->getWikiPage(), $context );
134
135 $this->assertType( $expected ?: 'null', $action );
136 }
137
138 public function emptyActionProvider() {
139 return [
140 [ null ],
141 [ false ],
142 [ '' ],
143 ];
144 }
145
146 /**
147 * @dataProvider emptyActionProvider
148 */
149 public function testEmptyAction_doesNotExist( $requestedAction ) {
150 $exists = Action::exists( $requestedAction );
151
152 $this->assertFalse( $exists );
153 }
154
155 /**
156 * @dataProvider emptyActionProvider
157 */
158 public function testEmptyAction_defaultsToView( $requestedAction ) {
159 $context = $this->getContext( $requestedAction );
160 $actionName = Action::getActionName( $context );
161
162 $this->assertEquals( 'view', $actionName );
163 }
164
165 /**
166 * @dataProvider emptyActionProvider
167 */
168 public function testEmptyAction_canNotBeInstantiated( $requestedAction ) {
169 $page = $this->getPage();
170 $action = Action::factory( $requestedAction, $page );
171
172 $this->assertNull( $action );
173 }
174
175 public function testDisabledAction_exists() {
176 $exists = Action::exists( 'disabled' );
177
178 $this->assertTrue( $exists );
179 }
180
181 public function testDisabledAction_isNotResolved() {
182 $context = $this->getContext( 'disabled' );
183 $actionName = Action::getActionName( $context );
184
185 $this->assertEquals( 'nosuchaction', $actionName );
186 }
187
188 public function testDisabledAction_factoryReturnsFalse() {
189 $page = $this->getPage();
190 $action = Action::factory( 'disabled', $page );
191
192 $this->assertFalse( $action );
193 }
194
195 public function dummyActionCallback() {
196 $context = $this->getContext();
197 return new CalledDummyAction( $context->getWikiPage(), $context );
198 }
199
200 }
201
202 class DummyAction extends Action {
203
204 public function getName() {
205 return static::class;
206 }
207
208 public function show() {
209 }
210
211 public function execute() {
212 }
213 }
214
215 class NamedDummyAction extends DummyAction {
216 }
217
218 class CalledDummyAction extends DummyAction {
219 }
220
221 class InstantiatedDummyAction extends DummyAction {
222 }