Merge "Remove use of BagOStuff TTL constants from unrelated code"
[mediawiki.git] / tests / phpunit / includes / api / query / ApiQuerySearchTest.php
blob92ecd1184140839655aa8e8b9322f6562ee8d1ad
1 <?php
3 namespace MediaWiki\Tests\Api\Query;
5 use ISearchResultSet;
6 use MediaWiki\MainConfigNames;
7 use MediaWiki\Revision\RevisionLookup;
8 use MediaWiki\Tests\Api\ApiTestCase;
9 use MediaWiki\Title\Title;
10 use MockSearchEngine;
11 use MockSearchResult;
12 use MockSearchResultSet;
14 /**
15 * @group medium
16 * @covers \MediaWiki\Api\ApiQuerySearch
18 class ApiQuerySearchTest extends ApiTestCase {
20 protected function setUp(): void {
21 parent::setUp();
22 MockSearchEngine::clearMockResults();
23 $this->registerMockSearchEngine();
24 $this->setService( 'RevisionLookup', $this->createMock( RevisionLookup::class ) );
27 private function registerMockSearchEngine() {
28 $this->overrideConfigValue( MainConfigNames::SearchType, MockSearchEngine::class );
31 public function provideSearchResults() {
32 return [
33 'empty search result' => [ [], [] ],
34 'has search results' => [
35 [ 'Zomg' ],
36 [ $this->mockResultClosure( 'Zomg' ) ],
38 'filters broken search results' => [
39 [ 'A', 'B' ],
41 $this->mockResultClosure( 'a' ),
42 $this->mockResultClosure( 'Zomg', [ 'setBrokenTitle' => true ] ),
43 $this->mockResultClosure( 'b' ),
46 'filters results with missing revision' => [
47 [ 'B', 'A' ],
49 $this->mockResultClosure( 'Zomg', [ 'setMissingRevision' => true ] ),
50 $this->mockResultClosure( 'b' ),
51 $this->mockResultClosure( 'a' ),
57 /**
58 * @dataProvider provideSearchResults
60 public function testSearchResults( $expect, $hits, array $params = [] ) {
61 MockSearchEngine::addMockResults( 'my query', $hits );
62 [ $response, $request ] = $this->doApiRequest( $params + [
63 'action' => 'query',
64 'list' => 'search',
65 'srsearch' => 'my query',
66 ] );
67 $titles = array_column( $response['query']['search'], 'title' );
68 $this->assertEquals( $expect, $titles );
71 public function provideInterwikiResults() {
72 return [
73 'empty' => [ [], [] ],
74 'one wiki response' => [
75 [ 'utwiki' => [ 'Qwerty' ] ],
77 ISearchResultSet::SECONDARY_RESULTS => [
78 'utwiki' => new MockSearchResultSet( [
79 $this->mockResultClosure(
80 'Qwerty',
81 [ 'setInterwikiPrefix' => 'utwiki' ]
83 ] ),
90 /**
91 * @dataProvider provideInterwikiResults
93 public function testInterwikiResults( $expect, $hits, array $params = [] ) {
94 MockSearchEngine::setMockInterwikiResults( $hits );
95 [ $response, $request ] = $this->doApiRequest( $params + [
96 'action' => 'query',
97 'list' => 'search',
98 'srsearch' => 'my query',
99 'srinterwiki' => true,
100 ] );
101 if ( !$expect ) {
102 $this->assertArrayNotHasKey( 'interwikisearch', $response['query'] );
103 return;
105 $results = [];
106 $this->assertArrayHasKey( 'interwikisearchinfo', $response['query'] );
107 foreach ( $response['query']['interwikisearch'] as $wiki => $wikiResults ) {
108 $results[$wiki] = [];
109 foreach ( $wikiResults as $wikiResult ) {
110 $results[$wiki][] = $wikiResult['title'];
113 $this->assertEquals( $expect, $results );
117 * Returns a closure that evaluates to a MockSearchResult, to be resolved by
118 * MockSearchEngine::addMockResults() or MockresultSet::extractResults().
120 * This is needed because MockSearchResults cannot be instantiated in a data provider,
121 * since they load revisions. This would hit the "real" database instead of the mock
122 * database, which in turn may cause cache pollution and other inconsistencies, see T202641.
124 * @param string $titleText
125 * @param array $setters
126 * @return callable function(): MockSearchResult
128 private function mockResultClosure( $titleText, $setters = [] ) {
129 return static function () use ( $titleText, $setters ) {
130 $title = Title::newFromText( $titleText );
131 $title->resetArticleID( 0 );
132 $result = new MockSearchResult( $title );
134 foreach ( $setters as $method => $param ) {
135 $result->$method( $param );
138 return $result;