8 class WatchActionTest
extends MediaWikiTestCase
{
18 private $testWikiPage;
20 protected function setUp() {
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 );
33 protected function tearDown() {
36 Hooks
::clear( 'WatchArticle' );
37 Hooks
::clear( 'UnwatchArticle' );
41 * @covers WatchAction::getName()
43 public function testGetName() {
44 $this->assertEquals( 'watch', $this->watchAction
->getName() );
48 * @covers WatchAction::requiresUnblock()
50 public function testRequiresUnlock() {
51 $this->assertFalse( $this->watchAction
->requiresUnblock() );
55 * @covers WatchAction::doesWrites()
57 public function testDoesWrites() {
58 $this->assertTrue( $this->watchAction
->doesWrites() );
62 * @covers WatchAction::onSubmit()
63 * @covers WatchAction::doWatch()
65 public function testOnSubmit() {
66 /** @var Status $actual */
67 $actual = $this->watchAction
->onSubmit( [] );
69 $this->assertTrue( $actual->isGood() );
73 * @covers WatchAction::onSubmit()
74 * @covers WatchAction::doWatch()
76 public function testOnSubmitHookAborted() {
77 Hooks
::register( 'WatchArticle', function () {
81 /** @var Status $actual */
82 $actual = $this->watchAction
->onSubmit( [] );
84 $this->assertInstanceOf( Status
::class, $actual );
85 $this->assertTrue( $actual->hasMessage( 'hookaborted' ) );
89 * @covers WatchAction::checkCanExecute()
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 );
102 * @covers WatchAction::checkCanExecute()
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 );
113 $watchAction->show();
114 } catch ( UserNotLoggedIn
$e ) {
117 $this->assertNull( $exception,
118 'UserNotLoggedIn exception should not be thrown if user is logged in.' );
122 * @covers WatchAction::onSuccess()
124 public function testOnSuccessMainNamespaceTitle() {
125 $testContext = $this->getMock(
126 DerivativeContext
::class,
128 [ $this->watchAction
->getContext() ]
130 $testOutput = new OutputPage( $testContext );
131 $testContext->setOutput( $testOutput );
132 $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
133 return new RawMessage( $msgKey );
135 $watchAction = new WatchAction( $this->testWikiPage
, $testContext );
137 $watchAction->onSuccess();
139 $this->assertEquals( '<p>addedwatchtext
140 </p>', $testOutput->getHTML() );
144 * @covers WatchAction::onSuccess()
146 public function testOnSuccessTalkPage() {
147 $testContext = $this->getMock(
148 DerivativeContext
::class,
150 [ $this->watchAction
->getContext() ]
152 $testOutput = new OutputPage( $testContext );
153 $testContext->method( 'getOutput' )->willReturn( $testOutput );
154 $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
155 return new RawMessage( $msgKey );
157 $talkPageTitle = Title
::newFromText( 'Talk:UTTest' );
158 $testContext->setTitle( $talkPageTitle );
159 $watchAction = new WatchAction( new WikiPage( $talkPageTitle ), $testContext );
161 $watchAction->onSuccess();
163 $this->assertEquals( '<p>addedwatchtext-talk
164 </p>', $testOutput->getHTML() );
168 * @covers WatchAction::doWatch()
171 public function testDoWatchNoCheckRights() {
172 $notPermittedUser = $this->getUser( null, null, [] );
173 $actual = WatchAction
::doWatch( $this->testWikiPage
->getTitle(), $notPermittedUser, false );
174 $this->assertTrue( $actual->isGood() );
178 * @covers WatchAction::doWatch()
181 public function testDoWatchUserNotPermittedStatusNotGood() {
182 $notPermittedUser = $this->getUser( null, null, [] );
183 $actual = WatchAction
::doWatch( $this->testWikiPage
->getTitle(), $notPermittedUser, true );
184 $this->assertFalse( $actual->isGood() );
188 * @covers WatchAction::doWatch()
191 public function testDoWatchCallsUserAddWatch() {
192 $permittedUser = $this->getUser( null, null, [ 'editmywatchlist' ] );
193 $permittedUser->expects( $this->once() )
194 ->method( 'addWatch' )
195 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ), $this->equalTo( true ) );
197 $actual = WatchAction
::doWatch( $this->testWikiPage
->getTitle(), $permittedUser );
199 $this->assertTrue( $actual->isGood() );
203 * @covers WatchAction::doUnWatch()
206 public function testDoUnWatchWithoutRights() {
207 $notPermittedUser = $this->getUser( null, null, [] );
208 $actual = WatchAction
::doUnWatch( $this->testWikiPage
->getTitle(), $notPermittedUser );
210 $this->assertFalse( $actual->isGood() );
214 * @covers WatchAction::doUnWatch()
216 public function testDoUnWatchUserHookAborted() {
217 $permittedUser = $this->getUser( null, null, [ 'editmywatchlist' ] );
218 Hooks
::register( 'UnwatchArticle', function () {
222 $status = WatchAction
::doUnWatch( $this->testWikiPage
->getTitle(), $permittedUser );
224 $this->assertFalse( $status->isGood() );
225 $errors = $status->getErrors();
226 $this->assertEquals( 1, count( $errors ) );
227 $this->assertEquals( 'hookaborted', $errors[0]['message'] );
231 * @covers WatchAction::doUnWatch()
234 public function testDoUnWatchCallsUserRemoveWatch() {
235 $permittedUser = $this->getUser( null, null, [ 'editmywatchlist' ] );
236 $permittedUser->expects( $this->once() )
237 ->method( 'removeWatch' )
238 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ) );
240 $actual = WatchAction
::doUnWatch( $this->testWikiPage
->getTitle(), $permittedUser );
242 $this->assertTrue( $actual->isGood() );
246 * @covers WatchAction::getWatchToken()
249 public function testGetWatchTokenNormalizesToWatch() {
250 $user = $this->getUser( null, null );
251 $user->expects( $this->once() )
252 ->method( 'getEditToken' )
253 ->with( $this->equalTo( 'watch' ) );
255 WatchAction
::getWatchToken( $this->watchAction
->getTitle(), $user, 'INVALID_ACTION' );
259 * @covers WatchAction::getWatchToken()
262 public function testGetWatchTokenProxiesUserGetEditToken() {
263 $user = $this->getUser( null, null );
264 $user->expects( $this->once() )->method( 'getEditToken' );
266 WatchAction
::getWatchToken( $this->watchAction
->getTitle(), $user );
270 * @covers WatchAction::doWatchOrUnwatch()
273 public function testDoWatchOrUnwatchUserNotLoggedIn() {
274 $user = $this->getUser( false );
275 $user->expects( $this->never() )->method( 'removeWatch' );
276 $user->expects( $this->never() )->method( 'addWatch' );
278 $status = WatchAction
::doWatchOrUnwatch( true, $this->watchAction
->getTitle(), $user );
280 $this->assertTrue( $status->isGood() );
284 * @covers WatchAction::doWatchOrUnwatch()
287 public function testDoWatchOrUnwatchSkipsIfAlreadyWatched() {
288 $user = $this->getUser();
289 $user->expects( $this->never() )->method( 'removeWatch' );
290 $user->expects( $this->never() )->method( 'addWatch' );
292 $status = WatchAction
::doWatchOrUnwatch( true, $this->watchAction
->getTitle(), $user );
294 $this->assertTrue( $status->isGood() );
298 * @covers WatchAction::doWatchOrUnwatch()
301 public function testDoWatchOrUnwatchSkipsIfAlreadyUnWatched() {
302 $user = $this->getUser( true, false );
303 $user->expects( $this->never() )->method( 'removeWatch' );
304 $user->expects( $this->never() )->method( 'addWatch' );
306 $status = WatchAction
::doWatchOrUnwatch( false, $this->watchAction
->getTitle(), $user );
308 $this->assertTrue( $status->isGood() );
312 * @covers WatchAction::doWatchOrUnwatch()
315 public function testDoWatchOrUnwatchWatchesIfWatch() {
316 $user = $this->getUser( 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 ) );
322 $status = WatchAction
::doWatchOrUnwatch( true, $this->watchAction
->getTitle(), $user );
324 $this->assertTrue( $status->isGood() );
328 * @covers WatchAction::doWatchOrUnwatch()
331 public function testDoWatchOrUnwatchUnwatchesIfUnwatch() {
332 $user = $this->getUser( true, true, [ 'editmywatchlist' ] );
333 $user->expects( $this->never() )->method( 'addWatch' );
334 $user->expects( $this->once() )
335 ->method( 'removeWatch' )
336 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ) );
338 $status = WatchAction
::doWatchOrUnwatch( false, $this->watchAction
->getTitle(), $user );
340 $this->assertTrue( $status->isGood() );
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 * @param array $permissions The permissions of the user
347 * @return PHPUnit_Framework_MockObject_MockObject
350 private function getUser(
355 $user = $this->getMock( User
::class );
356 $user->method( 'getId' )->willReturn( 42 );
357 $user->method( 'isLoggedIn' )->willReturn( $isLoggedIn );
358 $user->method( 'isWatched' )->willReturn( $isWatched );
359 $this->overrideUserPermissions( $user, $permissions );