Add doc-typehints to class properties found by the PropertyDocumentation sniff to improve the documentation. Once the sniff is enabled it avoids that new code is missing type declarations. This is focused on documentation and does not change code. Change-Id: I48014b6464f3e7e2b7f083e67f517af0b1a9367e
556 lines
16 KiB
PHP
556 lines
16 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Api\Query;
|
|
|
|
use MediaWiki\Tests\Api\ApiTestCase;
|
|
use MediaWiki\Title\TitleValue;
|
|
use MediaWiki\User\User;
|
|
use MediaWiki\Watchlist\WatchedItemQueryService;
|
|
|
|
/**
|
|
* @group API
|
|
* @group Database
|
|
* @group medium
|
|
*
|
|
* @covers \ApiQueryWatchlistRaw
|
|
*/
|
|
class ApiQueryWatchlistRawIntegrationTest extends ApiTestCase {
|
|
// TODO: This test should use Authority, but can't due to User::saveSettings
|
|
/** @var User */
|
|
private $loggedInUser;
|
|
/** @var User */
|
|
private $notLoggedInUser;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->loggedInUser = $this->getMutableTestUser()->getUser();
|
|
$this->notLoggedInUser = $this->getMutableTestUser()->getUser();
|
|
}
|
|
|
|
private function getLoggedInTestUser(): User {
|
|
return $this->loggedInUser;
|
|
}
|
|
|
|
private function getNotLoggedInTestUser(): User {
|
|
return $this->notLoggedInUser;
|
|
}
|
|
|
|
private function getWatchedItemStore() {
|
|
return $this->getServiceContainer()->getWatchedItemStore();
|
|
}
|
|
|
|
private function doListWatchlistRawRequest( array $params = [] ) {
|
|
return $this->doApiRequest( array_merge(
|
|
[ 'action' => 'query', 'list' => 'watchlistraw' ],
|
|
$params
|
|
), null, false, $this->getLoggedInTestUser() );
|
|
}
|
|
|
|
private function doGeneratorWatchlistRawRequest( array $params = [] ) {
|
|
return $this->doApiRequest( array_merge(
|
|
[ 'action' => 'query', 'generator' => 'watchlistraw' ],
|
|
$params
|
|
), null, false, $this->getLoggedInTestUser() );
|
|
}
|
|
|
|
private function getItemsFromApiResponse( array $response ) {
|
|
return $response[0]['watchlistraw'];
|
|
}
|
|
|
|
public function testListWatchlistRaw_returnsWatchedItems() {
|
|
$store = $this->getWatchedItemStore();
|
|
$store->addWatch(
|
|
$this->getLoggedInTestUser(),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage' )
|
|
);
|
|
|
|
$result = $this->doListWatchlistRawRequest();
|
|
|
|
$this->assertArrayHasKey( 'watchlistraw', $result[0] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testPropChanged_addsNotificationTimestamp() {
|
|
$target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage' );
|
|
$otherUser = $this->getNotLoggedInTestUser();
|
|
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatch( $this->getLoggedInTestUser(), $target );
|
|
$store->updateNotificationTimestamp(
|
|
$otherUser,
|
|
$target,
|
|
'20151212010101'
|
|
);
|
|
|
|
$result = $this->doListWatchlistRawRequest( [ 'wrprop' => 'changed' ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
'changed' => '2015-12-12T01:01:01Z',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testNamespaceParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage' ),
|
|
new TitleValue( NS_TALK, 'ApiQueryWatchlistRawIntegrationTestPage' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( [ 'wrnamespace' => '0' ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testShowChangedParams() {
|
|
$subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage' );
|
|
$talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistRawIntegrationTestPage' );
|
|
$otherUser = $this->getNotLoggedInTestUser();
|
|
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
$subjectTarget,
|
|
$talkTarget,
|
|
] );
|
|
$store->updateNotificationTimestamp(
|
|
$otherUser,
|
|
$subjectTarget,
|
|
'20151212010101'
|
|
);
|
|
|
|
$resultChanged = $this->doListWatchlistRawRequest(
|
|
[ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService::FILTER_CHANGED ]
|
|
);
|
|
$resultNotChanged = $this->doListWatchlistRawRequest(
|
|
[ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService::FILTER_NOT_CHANGED ]
|
|
);
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
'changed' => '2015-12-12T01:01:01Z',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultChanged )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_TALK,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultNotChanged )
|
|
);
|
|
}
|
|
|
|
public function testLimitParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_TALK, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
] );
|
|
|
|
$resultWithoutLimit = $this->doListWatchlistRawRequest();
|
|
$resultWithLimit = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => NS_TALK,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultWithoutLimit )
|
|
);
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultWithLimit )
|
|
);
|
|
|
|
$this->assertArrayNotHasKey( 'continue', $resultWithoutLimit[0] );
|
|
$this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
|
|
$this->assertArrayHasKey( 'wrcontinue', $resultWithLimit[0]['continue'] );
|
|
}
|
|
|
|
public function testDirParams() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_TALK, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
] );
|
|
|
|
$resultDirAsc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
|
|
$resultDirDesc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'descending' ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => NS_TALK,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultDirAsc )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_TALK,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultDirDesc )
|
|
);
|
|
}
|
|
|
|
public function testAscendingIsDefaultOrder() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_TALK, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
] );
|
|
|
|
$resultNoDir = $this->doListWatchlistRawRequest();
|
|
$resultAscDir = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
|
|
|
|
$this->assertEquals(
|
|
$this->getItemsFromApiResponse( $resultNoDir ),
|
|
$this->getItemsFromApiResponse( $resultAscDir )
|
|
);
|
|
}
|
|
|
|
public function testFromTitleParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( [
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testToTitleParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( [
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testContinueParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$firstResult = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
|
|
$continuationParam = $firstResult[0]['continue']['wrcontinue'];
|
|
|
|
$this->assertSame( '0|ApiQueryWatchlistRawIntegrationTestPage3', $continuationParam );
|
|
|
|
$continuedResult = $this->doListWatchlistRawRequest( [ 'wrcontinue' => $continuationParam ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
]
|
|
],
|
|
$this->getItemsFromApiResponse( $continuedResult )
|
|
);
|
|
}
|
|
|
|
public static function fromTitleToTitleContinueComboProvider() {
|
|
return [
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
[ 'ns' => NS_MAIN, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1' ],
|
|
[ 'ns' => NS_MAIN, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
|
|
],
|
|
],
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
|
|
],
|
|
[
|
|
[ 'ns' => NS_MAIN, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
|
|
],
|
|
],
|
|
[
|
|
[
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
[ 'ns' => NS_MAIN, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
|
|
[ 'ns' => NS_MAIN, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
|
|
],
|
|
],
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
|
|
],
|
|
[
|
|
[ 'ns' => NS_MAIN, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider fromTitleToTitleContinueComboProvider
|
|
*/
|
|
public function testFromTitleToTitleContinueCombo( array $params, array $expectedItems ) {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( $params );
|
|
|
|
$this->assertEquals( $expectedItems, $this->getItemsFromApiResponse( $result ) );
|
|
}
|
|
|
|
public static function fromTitleToTitleContinueSelfContradictoryComboProvider() {
|
|
return [
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
'wrdir' => 'descending',
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
|
|
]
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider fromTitleToTitleContinueSelfContradictoryComboProvider
|
|
*/
|
|
public function testFromTitleToTitleContinueSelfContradictoryCombo( array $params ) {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( $params );
|
|
|
|
$this->assertSame( [], $this->getItemsFromApiResponse( $result ) );
|
|
$this->assertArrayNotHasKey( 'continue', $result[0] );
|
|
}
|
|
|
|
public function testOwnerAndTokenParams() {
|
|
$services = $this->getServiceContainer();
|
|
$userOptionsManager = $services->getUserOptionsManager();
|
|
|
|
$otherUser = $this->getNotLoggedInTestUser();
|
|
$userOptionsManager->setOption( $otherUser, 'watchlisttoken', '1234567890' );
|
|
$otherUser->saveSettings();
|
|
|
|
$store = $this->getWatchedItemStore();
|
|
$store->addWatchBatchForUser( $otherUser, [
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( NS_TALK, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
] );
|
|
|
|
$services->getMainWANObjectCache()->clearProcessCache();
|
|
$result = $this->doListWatchlistRawRequest( [
|
|
'wrowner' => $otherUser->getName(),
|
|
'wrtoken' => '1234567890',
|
|
] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => NS_MAIN,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => NS_TALK,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testOwnerAndTokenParams_wrongToken() {
|
|
$userOptionsManager = $this->getServiceContainer()->getUserOptionsManager();
|
|
|
|
$otherUser = $this->getNotLoggedInTestUser();
|
|
$userOptionsManager->setOption( $otherUser, 'watchlisttoken', '1234567890' );
|
|
$otherUser->saveSettings();
|
|
|
|
$this->expectApiErrorCode( 'bad_wltoken' );
|
|
|
|
$this->doListWatchlistRawRequest( [
|
|
'wrowner' => $otherUser->getName(),
|
|
'wrtoken' => 'wrong-token',
|
|
] );
|
|
}
|
|
|
|
public function testOwnerAndTokenParams_userHasNoWatchlistToken() {
|
|
$this->expectApiErrorCode( 'bad_wltoken' );
|
|
|
|
$this->doListWatchlistRawRequest( [
|
|
'wrowner' => $this->getNotLoggedInTestUser()->getName(),
|
|
'wrtoken' => 'some-watchlist-token',
|
|
] );
|
|
}
|
|
|
|
public function testGeneratorWatchlistRawPropInfo_returnsWatchedItems() {
|
|
$store = $this->getWatchedItemStore();
|
|
$store->addWatch(
|
|
$this->getLoggedInTestUser(),
|
|
new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage' )
|
|
);
|
|
|
|
$result = $this->doGeneratorWatchlistRawRequest( [ 'prop' => 'info' ] );
|
|
|
|
$this->assertArrayHasKey( 'query', $result[0] );
|
|
$this->assertArrayHasKey( 'pages', $result[0]['query'] );
|
|
$this->assertCount( 1, $result[0]['query']['pages'] );
|
|
|
|
// $result[0]['query']['pages'] uses page ids as keys
|
|
$item = array_values( $result[0]['query']['pages'] )[0];
|
|
|
|
$this->assertSame( NS_MAIN, $item['ns'] );
|
|
$this->assertEquals( 'ApiQueryWatchlistRawIntegrationTestPage', $item['title'] );
|
|
}
|
|
|
|
}
|