Merge "Add another Bengali synonym for HIDDENCAT in MessagesBn.php"
[lhc/web/wiklou.git] / tests / phpunit / includes / actions / WatchActionTest.php
1 <?php
2
3 /**
4 * @covers WatchAction
5 *
6 * @group Action
7 */
8 class WatchActionTest extends MediaWikiTestCase {
9
10 /**
11 * @var WatchAction
12 */
13 private $watchAction;
14
15 /**
16 * @var WikiPage
17 */
18 private $testWikiPage;
19
20 protected function setUp() {
21 parent::setUp();
22
23 $testTitle = Title::newFromText( 'UTTest' );
24 $this->testWikiPage = new WikiPage( $testTitle );
25 $testContext = new DerivativeContext( RequestContext::getMain() );
26 $testContext->setTitle( $testTitle );
27 $this->watchAction = new WatchAction( $this->testWikiPage, $testContext );
28 }
29
30 /**
31 * @throws MWException
32 */
33 protected function tearDown() {
34 parent::tearDown();
35
36 Hooks::clear( 'WatchArticle' );
37 Hooks::clear( 'UnwatchArticle' );
38 }
39
40 /**
41 * @covers WatchAction::getName()
42 */
43 public function testGetName() {
44 $this->assertEquals( 'watch', $this->watchAction->getName() );
45 }
46
47 /**
48 * @covers WatchAction::requiresUnblock()
49 */
50 public function testRequiresUnlock() {
51 $this->assertFalse( $this->watchAction->requiresUnblock() );
52 }
53
54 /**
55 * @covers WatchAction::doesWrites()
56 */
57 public function testDoesWrites() {
58 $this->assertTrue( $this->watchAction->doesWrites() );
59 }
60
61 /**
62 * @covers WatchAction::onSubmit()
63 * @covers WatchAction::doWatch()
64 */
65 public function testOnSubmit() {
66 /** @var Status $actual */
67 $actual = $this->watchAction->onSubmit( [] );
68
69 $this->assertTrue( $actual->isGood() );
70 }
71
72 /**
73 * @covers WatchAction::onSubmit()
74 * @covers WatchAction::doWatch()
75 */
76 public function testOnSubmitHookAborted() {
77 Hooks::register( 'WatchArticle', function () {
78 return false;
79 } );
80
81 /** @var Status $actual */
82 $actual = $this->watchAction->onSubmit( [] );
83
84 $this->assertInstanceOf( Status::class, $actual );
85 $this->assertTrue( $actual->hasMessage( 'hookaborted' ) );
86 }
87
88 /**
89 * @covers WatchAction::checkCanExecute()
90 */
91 public function testShowUserNotLoggedIn() {
92 $notLoggedInUser = new User();
93 $testContext = new DerivativeContext( $this->watchAction->getContext() );
94 $testContext->setUser( $notLoggedInUser );
95 $watchAction = new WatchAction( $this->testWikiPage, $testContext );
96 $this->setExpectedException( UserNotLoggedIn::class );
97
98 $watchAction->show();
99 }
100
101 /**
102 * @covers WatchAction::checkCanExecute()
103 */
104 public function testShowUserLoggedInNoException() {
105 $loggedInUser = $this->getMock( User::class );
106 $loggedInUser->method( 'isLoggedIn' )->willReturn( true );
107 $testContext = new DerivativeContext( $this->watchAction->getContext() );
108 $testContext->setUser( $loggedInUser );
109 $watchAction = new WatchAction( $this->testWikiPage, $testContext );
110
111 $exception = null;
112 try {
113 $watchAction->show();
114 } catch ( UserNotLoggedIn $e ) {
115 $exception = $e;
116 }
117 $this->assertNull( $exception,
118 'UserNotLoggedIn exception should not be thrown if user is logged in.' );
119 }
120
121 /**
122 * @covers WatchAction::onSuccess()
123 */
124 public function testOnSuccessMainNamespaceTitle() {
125 $testContext = $this->getMock(
126 DerivativeContext::class,
127 [ 'msg' ],
128 [ $this->watchAction->getContext() ]
129 );
130 $testOutput = new OutputPage( $testContext );
131 $testContext->setOutput( $testOutput );
132 $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
133 return new RawMessage( $msgKey );
134 } );
135 $watchAction = new WatchAction( $this->testWikiPage, $testContext );
136
137 $watchAction->onSuccess();
138
139 $this->assertEquals( '<p>addedwatchtext
140 </p>', $testOutput->getHTML() );
141 }
142
143 /**
144 * @covers WatchAction::onSuccess()
145 */
146 public function testOnSuccessTalkPage() {
147 $testContext = $this->getMock(
148 DerivativeContext::class,
149 [],
150 [ $this->watchAction->getContext() ]
151 );
152 $testOutput = new OutputPage( $testContext );
153 $testContext->method( 'getOutput' )->willReturn( $testOutput );
154 $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
155 return new RawMessage( $msgKey );
156 } );
157 $talkPageTitle = Title::newFromText( 'Talk:UTTest' );
158 $testContext->setTitle( $talkPageTitle );
159 $watchAction = new WatchAction( new WikiPage( $talkPageTitle ), $testContext );
160
161 $watchAction->onSuccess();
162
163 $this->assertEquals( '<p>addedwatchtext-talk
164 </p>', $testOutput->getHTML() );
165 }
166
167 /**
168 * @covers WatchAction::doWatch()
169 */
170 public function testDoWatchNoCheckRights() {
171 $notPermittedUser = $this->getMock( User::class );
172 $notPermittedUser->method( 'isAllowed' )->willReturn( false );
173
174 $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, false );
175
176 $this->assertTrue( $actual->isGood() );
177 }
178
179 /**
180 * @covers WatchAction::doWatch()
181 */
182 public function testDoWatchUserNotPermittedStatusNotGood() {
183 $notPermittedUser = $this->getMock( User::class );
184 $notPermittedUser->method( 'isAllowed' )->willReturn( false );
185
186 $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, true );
187
188 $this->assertFalse( $actual->isGood() );
189 }
190
191 /**
192 * @covers WatchAction::doWatch()
193 */
194 public function testDoWatchCallsUserAddWatch() {
195 $permittedUser = $this->getMock( User::class );
196 $permittedUser->method( 'isAllowed' )->willReturn( true );
197 $permittedUser->expects( $this->once() )
198 ->method( 'addWatch' )
199 ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( true ) );
200
201 $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $permittedUser );
202
203 $this->assertTrue( $actual->isGood() );
204 }
205
206 /**
207 * @covers WatchAction::doUnWatch()
208 */
209 public function testDoUnWatchWithoutRights() {
210 $notPermittedUser = $this->getMock( User::class );
211 $notPermittedUser->method( 'isAllowed' )->willReturn( false );
212
213 $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $notPermittedUser );
214
215 $this->assertFalse( $actual->isGood() );
216 }
217
218 /**
219 * @covers WatchAction::doUnWatch()
220 */
221 public function testDoUnWatchUserHookAborted() {
222 $permittedUser = $this->getMock( User::class );
223 $permittedUser->method( 'isAllowed' )->willReturn( true );
224 Hooks::register( 'UnwatchArticle', function () {
225 return false;
226 } );
227
228 $status = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
229
230 $this->assertFalse( $status->isGood() );
231 $errors = $status->getErrors();
232 $this->assertEquals( 1, count( $errors ) );
233 $this->assertEquals( 'hookaborted', $errors[0]['message'] );
234 }
235
236 /**
237 * @covers WatchAction::doUnWatch()
238 */
239 public function testDoUnWatchCallsUserRemoveWatch() {
240 $permittedUser = $this->getMock( User::class );
241 $permittedUser->method( 'isAllowed' )->willReturn( true );
242 $permittedUser->expects( $this->once() )
243 ->method( 'removeWatch' )
244 ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
245
246 $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
247
248 $this->assertTrue( $actual->isGood() );
249 }
250
251 /**
252 * @covers WatchAction::getWatchToken()
253 */
254 public function testGetWatchTokenNormalizesToWatch() {
255 $user = $this->getMock( User::class );
256 $user->expects( $this->once() )
257 ->method( 'getEditToken' )
258 ->with( $this->equalTo( 'watch' ) );
259
260 WatchAction::getWatchToken( $this->watchAction->getTitle(), $user, 'INVALID_ACTION' );
261 }
262
263 /**
264 * @covers WatchAction::getWatchToken()
265 */
266 public function testGetWatchTokenProxiesUserGetEditToken() {
267 $user = $this->getMock( User::class );
268 $user->expects( $this->once() )->method( 'getEditToken' );
269
270 WatchAction::getWatchToken( $this->watchAction->getTitle(), $user );
271 }
272
273 /**
274 * @covers WatchAction::doWatchOrUnwatch()
275 */
276 public function testDoWatchOrUnwatchUserNotLoggedIn() {
277 $user = $this->getLoggedInIsWatchedUser( false );
278 $user->expects( $this->never() )->method( 'removeWatch' );
279 $user->expects( $this->never() )->method( 'addWatch' );
280
281 $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
282
283 $this->assertTrue( $status->isGood() );
284 }
285
286 /**
287 * @covers WatchAction::doWatchOrUnwatch()
288 */
289 public function testDoWatchOrUnwatchSkipsIfAlreadyWatched() {
290 $user = $this->getLoggedInIsWatchedUser();
291 $user->expects( $this->never() )->method( 'removeWatch' );
292 $user->expects( $this->never() )->method( 'addWatch' );
293
294 $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
295
296 $this->assertTrue( $status->isGood() );
297 }
298
299 /**
300 * @covers WatchAction::doWatchOrUnwatch()
301 */
302 public function testDoWatchOrUnwatchSkipsIfAlreadyUnWatched() {
303 $user = $this->getLoggedInIsWatchedUser( true, false );
304 $user->expects( $this->never() )->method( 'removeWatch' );
305 $user->expects( $this->never() )->method( 'addWatch' );
306
307 $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
308
309 $this->assertTrue( $status->isGood() );
310 }
311
312 /**
313 * @covers WatchAction::doWatchOrUnwatch()
314 */
315 public function testDoWatchOrUnwatchWatchesIfWatch() {
316 $user = $this->getLoggedInIsWatchedUser( true, false );
317 $user->expects( $this->never() )->method( 'removeWatch' );
318 $user->expects( $this->once() )
319 ->method( 'addWatch' )
320 ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( false ) );
321
322 $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
323
324 $this->assertTrue( $status->isGood() );
325 }
326
327 /**
328 * @covers WatchAction::doWatchOrUnwatch()
329 */
330 public function testDoWatchOrUnwatchUnwatchesIfUnwatch() {
331 $user = $this->getLoggedInIsWatchedUser();
332 $user->method( 'isAllowed' )->willReturn( true );
333 $user->expects( $this->never() )->method( 'addWatch' );
334 $user->expects( $this->once() )
335 ->method( 'removeWatch' )
336 ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
337
338 $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
339
340 $this->assertTrue( $status->isGood() );
341 }
342
343 /**
344 * @param bool $isLoggedIn Whether the user should be "marked" as logged in
345 * @param bool $isWatched The value any call to isWatched should return
346 * @return PHPUnit_Framework_MockObject_MockObject
347 */
348 private function getLoggedInIsWatchedUser( $isLoggedIn = true, $isWatched = true ) {
349 $user = $this->getMock( User::class );
350 $user->method( 'isLoggedIn' )->willReturn( $isLoggedIn );
351 $user->method( 'isWatched' )->willReturn( $isWatched );
352
353 return $user;
354 }
355
356 }