This property shouldn't be needed in modern code, where most things can use Authority. So much so because TestUser adds a dependency on the database, but many tests that use TestUser don't even need the database. ApiTestCase, in particular, sets this property in setUp, thus adding a database dependency to all API tests, including those that don't need users or the database at all. Deprecate the property and replace existing usages in core. The one in ApiTestCase is much harder to migrate, but this patch replaces the array with an anonymous ArrayAccess class to allow lazy initialization and remove DB dependencies. Bug: T155147 Change-Id: I59c4ed1f6a7572d3a92387b15b8e56625bc376a2
552 lines
15 KiB
PHP
552 lines
15 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @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
|
|
private $loggedInUser;
|
|
private $notLoggedInUser;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->tablesUsed = array_merge(
|
|
$this->tablesUsed,
|
|
[ 'watchlist', 'watchlist_expiry' ]
|
|
);
|
|
|
|
$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( 0, 'ApiQueryWatchlistRawIntegrationTestPage' )
|
|
);
|
|
|
|
$result = $this->doListWatchlistRawRequest();
|
|
|
|
$this->assertArrayHasKey( 'watchlistraw', $result[0] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testPropChanged_addsNotificationTimestamp() {
|
|
$target = new TitleValue( 0, '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' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
'changed' => '2015-12-12T01:01:01Z',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testNamespaceParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' ),
|
|
new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( [ 'wrnamespace' => '0' ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testShowChangedParams() {
|
|
$subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' );
|
|
$talkTarget = new TitleValue( 1, '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' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
|
|
'changed' => '2015-12-12T01:01:01Z',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultChanged )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 1,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultNotChanged )
|
|
);
|
|
}
|
|
|
|
public function testLimitParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
] );
|
|
|
|
$resultWithoutLimit = $this->doListWatchlistRawRequest();
|
|
$resultWithLimit = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => 1,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultWithoutLimit )
|
|
);
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'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( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
] );
|
|
|
|
$resultDirAsc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
|
|
$resultDirDesc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'descending' ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => 1,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultDirAsc )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 1,
|
|
'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $resultDirDesc )
|
|
);
|
|
}
|
|
|
|
public function testAscendingIsDefaultOrder() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, '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( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( [
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testToTitleParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$result = $this->doListWatchlistRawRequest( [
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
],
|
|
$this->getItemsFromApiResponse( $result )
|
|
);
|
|
}
|
|
|
|
public function testContinueParam() {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
|
|
] );
|
|
|
|
$firstResult = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
|
|
$continuationParam = $firstResult[0]['continue']['wrcontinue'];
|
|
|
|
$this->assertSame( '0|ApiQueryWatchlistRawIntegrationTestPage3', $continuationParam );
|
|
|
|
$continuedResult = $this->doListWatchlistRawRequest( [ 'wrcontinue' => $continuationParam ] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
]
|
|
],
|
|
$this->getItemsFromApiResponse( $continuedResult )
|
|
);
|
|
}
|
|
|
|
public static function fromTitleToTitleContinueComboProvider() {
|
|
return [
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
[ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1' ],
|
|
[ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
|
|
],
|
|
],
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
|
|
],
|
|
[
|
|
[ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
|
|
],
|
|
],
|
|
[
|
|
[
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
|
|
],
|
|
[
|
|
[ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
|
|
[ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
|
|
],
|
|
],
|
|
[
|
|
[
|
|
'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
|
|
'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
|
|
],
|
|
[
|
|
[ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider fromTitleToTitleContinueComboProvider
|
|
*/
|
|
public function testFromTitleToTitleContinueCombo( array $params, array $expectedItems ) {
|
|
$store = $this->getWatchedItemStore();
|
|
|
|
$store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
|
|
new TitleValue( 0, '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( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 0, '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( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
|
|
] );
|
|
|
|
$services->getMainWANObjectCache()->clearProcessCache();
|
|
$result = $this->doListWatchlistRawRequest( [
|
|
'wrowner' => $otherUser->getName(),
|
|
'wrtoken' => '1234567890',
|
|
] );
|
|
|
|
$this->assertEquals(
|
|
[
|
|
[
|
|
'ns' => 0,
|
|
'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
|
|
],
|
|
[
|
|
'ns' => 1,
|
|
'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( 0, '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( 0, $item['ns'] );
|
|
$this->assertEquals( 'ApiQueryWatchlistRawIntegrationTestPage', $item['title'] );
|
|
}
|
|
|
|
}
|