Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / tests / phpunit / includes / api / ApiQuerySearchTest.php
1 <?php
2
3 /**
4 * @group medium
5 * @covers ApiQuerySearch
6 */
7 class ApiQuerySearchTest extends ApiTestCase {
8 public function provideSearchResults() {
9 return [
10 'empty search result' => [ [], [] ],
11 'has search results' => [
12 [ 'Zomg' ],
13 [ $this->mockResultClosure( 'Zomg' ) ],
14 ],
15 'filters broken search results' => [
16 [ 'A', 'B' ],
17 [
18 $this->mockResultClosure( 'a' ),
19 $this->mockResultClosure( 'Zomg', [ 'setBrokenTitle' => true ] ),
20 $this->mockResultClosure( 'b' ),
21 ],
22 ],
23 'filters results with missing revision' => [
24 [ 'B', 'A' ],
25 [
26 $this->mockResultClosure( 'Zomg', [ 'setMissingRevision' => true ] ),
27 $this->mockResultClosure( 'b' ),
28 $this->mockResultClosure( 'a' ),
29 ],
30 ],
31 ];
32 }
33
34 /**
35 * @dataProvider provideSearchResults
36 */
37 public function testSearchResults( $expect, $hits, array $params = [] ) {
38 MockSearchEngine::addMockResults( 'my query', $hits );
39 list( $response, $request ) = $this->doApiRequest( $params + [
40 'action' => 'query',
41 'list' => 'search',
42 'srsearch' => 'my query',
43 ] );
44 $titles = [];
45 foreach ( $response['query']['search'] as $result ) {
46 $titles[] = $result['title'];
47 }
48 $this->assertEquals( $expect, $titles );
49 }
50
51 public function provideInterwikiResults() {
52 return [
53 'empty' => [ [], [] ],
54 'one wiki response' => [
55 [ 'utwiki' => [ 'Qwerty' ] ],
56 [
57 ISearchResultSet::SECONDARY_RESULTS => [
58 'utwiki' => new MockSearchResultSet( [
59 $this->mockResultClosure(
60 'Qwerty',
61 [ 'setInterwikiPrefix' => 'utwiki' ]
62 ),
63 ] ),
64 ],
65 ]
66 ],
67 ];
68 }
69
70 /**
71 * @dataProvider provideInterwikiResults
72 */
73 public function testInterwikiResults( $expect, $hits, array $params = [] ) {
74 MockSearchEngine::setMockInterwikiResults( $hits );
75 list( $response, $request ) = $this->doApiRequest( $params + [
76 'action' => 'query',
77 'list' => 'search',
78 'srsearch' => 'my query',
79 'srinterwiki' => true,
80 ] );
81 if ( !$expect ) {
82 $this->assertArrayNotHasKey( 'interwikisearch', $response['query'] );
83 return;
84 }
85 $results = [];
86 $this->assertArrayHasKey( 'interwikisearchinfo', $response['query'] );
87 foreach ( $response['query']['interwikisearch'] as $wiki => $wikiResults ) {
88 $results[$wiki] = [];
89 foreach ( $wikiResults as $wikiResult ) {
90 $results[$wiki][] = $wikiResult['title'];
91 }
92 }
93 $this->assertEquals( $expect, $results );
94 }
95
96 public function setUp() {
97 parent::setUp();
98 MockSearchEngine::clearMockResults();
99 $this->registerMockSearchEngine();
100 }
101
102 private function registerMockSearchEngine() {
103 $this->setMwGlobals( [
104 'wgSearchType' => MockSearchEngine::class,
105 ] );
106 }
107
108 /**
109 * Returns a closure that evaluates to a MockSearchResult, to be resolved by
110 * MockSearchEngine::addMockResults() or MockresultSet::extractResults().
111 *
112 * This is needed because MockSearchResults cannot be instantiated in a data provider,
113 * since they load revisions. This would hit the "real" database instead of the mock
114 * database, which in turn may cause cache pollution and other inconsistencies, see T202641.
115 *
116 * @param string $title
117 * @param array $setters
118 * @return callable function(): MockSearchResult
119 */
120 private function mockResultClosure( $title, $setters = [] ) {
121 return function () use ( $title, $setters ){
122 $result = MockSearchResult::newFromTitle( Title::newFromText( $title ) );
123
124 foreach ( $setters as $method => $param ) {
125 $result->$method( $param );
126 }
127
128 return $result;
129 };
130 }
131
132 }