Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F5978092
SearchEnginePrefixTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
SearchEnginePrefixTest.php
View Options
<?php
use
MediaWiki\MainConfigNames
;
use
MediaWiki\Title\Title
;
/**
* @group Search
* @group Database
*/
class
SearchEnginePrefixTest
extends
MediaWikiLangTestCase
{
private
SearchEngine
$search
;
public
function
addDBDataOnce
()
{
if
(
!
$this
->
isWikitextNS
(
NS_MAIN
)
)
{
// tests are skipped if NS_MAIN is not wikitext
return
;
}
$this
->
insertPage
(
'Sandbox'
);
$this
->
insertPage
(
'Bar'
);
$this
->
insertPage
(
'Example'
);
$this
->
insertPage
(
'Example Bar'
);
$this
->
insertPage
(
'Example Foo'
);
$this
->
insertPage
(
'Example Foo/Bar'
);
$this
->
insertPage
(
'Example/Baz'
);
$this
->
insertPage
(
'Sample'
);
$this
->
insertPage
(
'Sample Ban'
);
$this
->
insertPage
(
'Sample Eat'
);
$this
->
insertPage
(
'Sample Who'
);
$this
->
insertPage
(
'Sample Zoo'
);
$this
->
insertPage
(
'Redirect test'
,
'#REDIRECT [[Redirect Test]]'
);
$this
->
insertPage
(
'Redirect Test'
);
$this
->
insertPage
(
'Redirect Test Worse Result'
);
$this
->
insertPage
(
'Redirect test2'
,
'#REDIRECT [[Redirect Test2]]'
);
$this
->
insertPage
(
'Redirect TEST2'
,
'#REDIRECT [[Redirect Test2]]'
);
$this
->
insertPage
(
'Redirect Test2'
);
$this
->
insertPage
(
'Redirect Test2 Worse Result'
);
$this
->
insertPage
(
'Talk:Sandbox'
);
$this
->
insertPage
(
'Talk:Example'
);
$this
->
insertPage
(
'User:Example'
);
$this
->
insertPage
(
'Barcelona'
);
$this
->
insertPage
(
'Barbara'
);
$this
->
insertPage
(
'External'
);
}
protected
function
setUp
():
void
{
parent
::
setUp
();
if
(
!
$this
->
isWikitextNS
(
NS_MAIN
)
)
{
$this
->
markTestSkipped
(
'Main namespace does not support wikitext.'
);
}
// Avoid special pages from extensions interferring with the tests
$this
->
overrideConfigValues
(
[
MainConfigNames
::
SpecialPages
=>
[],
MainConfigNames
::
Hooks
=>
[],
]
);
$this
->
search
=
$this
->
getServiceContainer
()->
newSearchEngine
();
$this
->
search
->
setNamespaces
(
[]
);
}
protected
function
searchProvision
(
?
array
$results
=
null
)
{
if
(
$results
===
null
)
{
$this
->
overrideConfigValue
(
MainConfigNames
::
Hooks
,
[]
);
}
else
{
$this
->
setTemporaryHook
(
'PrefixSearchBackend'
,
static
function
(
$namespaces
,
$search
,
$limit
,
&
$srchres
)
use
(
$results
)
{
$srchres
=
$results
;
return
false
;
}
);
}
}
public
static
function
provideSearch
()
{
return
[
[
[
'Empty string'
,
'query'
=>
''
,
'results'
=>
[],
]
],
[
[
'All invalid characters, effectively empty'
,
'query'
=>
'['
,
'results'
=>
[],
]
],
[
[
'Main namespace with title prefix'
,
'query'
=>
'Sa'
,
'results'
=>
[
'Sample'
,
'Sample Ban'
,
'Sample Eat'
,
],
// Third result when testing offset
'offsetresult'
=>
[
'Sample Who'
,
],
]
],
[
[
'Some invalid characters'
,
'query'
=>
'[[Sa]]'
,
'results'
=>
[
'Sample'
,
'Sample Ban'
,
'Sample Eat'
,
],
'offsetresult'
=>
[
'Sample Who'
],
]
],
[
[
'Talk namespace prefix'
,
'query'
=>
'Talk:'
,
'results'
=>
[
'Talk:Example'
,
'Talk:Sandbox'
,
],
]
],
[
[
'User namespace prefix'
,
'query'
=>
'User:'
,
'results'
=>
[
'User:Example'
,
],
]
],
[
[
'Special namespace prefix'
,
'query'
=>
'Special:'
,
'results'
=>
[
'Special:ActiveUsers'
,
'Special:AllMessages'
,
'Special:AllPages'
,
],
// Third result when testing offset
'offsetresult'
=>
[
'Special:AncientPages'
,
],
]
],
[
[
'Special namespace with prefix'
,
'query'
=>
'Special:Un'
,
'results'
=>
[
'Special:Unblock'
,
'Special:UncategorizedCategories'
,
'Special:UncategorizedFiles'
,
],
// Third result when testing offset
'offsetresult'
=>
[
'Special:UncategorizedPages'
,
],
]
],
[
[
'Special page name'
,
'query'
=>
'Special:EditWatchlist'
,
'results'
=>
[
],
]
],
[
[
'Special page subpages'
,
'query'
=>
'Special:EditWatchlist/'
,
'results'
=>
[
'Special:EditWatchlist/clear'
,
'Special:EditWatchlist/raw'
,
],
]
],
[
[
'Special page subpages with prefix'
,
'query'
=>
'Special:EditWatchlist/cl'
,
'results'
=>
[
'Special:EditWatchlist/clear'
,
],
]
],
];
}
/**
* @dataProvider provideSearch
* @covers \SearchEngine::defaultPrefixSearch
*/
public
function
testSearch
(
array
$case
)
{
$this
->
search
->
setLimitOffset
(
3
);
$results
=
$this
->
search
->
defaultPrefixSearch
(
$case
[
'query'
]
);
$results
=
array_map
(
static
function
(
Title
$t
)
{
return
$t
->
getPrefixedText
();
},
$results
);
$this
->
assertEquals
(
$case
[
'results'
],
$results
,
$case
[
0
]
);
}
/**
* @dataProvider provideSearch
* @covers \SearchEngine::defaultPrefixSearch
*/
public
function
testSearchWithOffset
(
array
$case
)
{
$this
->
search
->
setLimitOffset
(
3
,
1
);
$results
=
$this
->
search
->
defaultPrefixSearch
(
$case
[
'query'
]
);
$results
=
array_map
(
static
function
(
Title
$t
)
{
return
$t
->
getPrefixedText
();
},
$results
);
// We don't expect the first result when offsetting
array_shift
(
$case
[
'results'
]
);
// And sometimes we expect a different last result
$expected
=
isset
(
$case
[
'offsetresult'
]
)
?
array_merge
(
$case
[
'results'
],
$case
[
'offsetresult'
]
)
:
$case
[
'results'
];
$this
->
assertEquals
(
$expected
,
$results
,
$case
[
0
]
);
}
public
static
function
provideSearchBackend
()
{
return
[
[
[
'Simple case'
,
'provision'
=>
[
'Bar'
,
'Barcelona'
,
'Barbara'
,
],
'query'
=>
'Bar'
,
'results'
=>
[
'Bar'
,
'Barcelona'
,
'Barbara'
,
],
]
],
[
[
'Exact match not in first result should be moved to the first result (T72958)'
,
'provision'
=>
[
'Barcelona'
,
'Bar'
,
'Barbara'
,
],
'query'
=>
'Bar'
,
'results'
=>
[
'Bar'
,
'Barcelona'
,
'Barbara'
,
],
]
],
[
[
'Exact match missing from results should be added as first result (T72958)'
,
'provision'
=>
[
'Barcelona'
,
'Barbara'
,
'Bart'
,
],
'query'
=>
'Bar'
,
'results'
=>
[
'Bar'
,
'Barcelona'
,
'Barbara'
,
],
]
],
[
[
'Exact match missing and not existing pages should be dropped'
,
'provision'
=>
[
'Exile'
,
'Exist'
,
'External'
,
],
'query'
=>
'Ex'
,
'results'
=>
[
'External'
,
],
]
],
[
[
"Exact match shouldn't override already found match if "
.
"exact is redirect and found isn't"
,
'provision'
=>
[
// Target of the exact match is low in the list
'Redirect Test Worse Result'
,
'Redirect Test'
,
],
'query'
=>
'redirect test'
,
'results'
=>
[
// Redirect target is pulled up and exact match isn't added
'Redirect Test'
,
'Redirect Test Worse Result'
,
],
]
],
[
[
"Exact match should override already found match if "
.
"both exact match and found match are redirect"
,
'provision'
=>
[
// Another redirect to the same target as the exact match
// is low in the list
'Redirect Test2 Worse Result'
,
'Redirect test2'
,
],
'query'
=>
'redirect TEST2'
,
'results'
=>
[
// Found redirect is pulled to the top and exact match isn't
// added
'Redirect TEST2'
,
'Redirect Test2 Worse Result'
,
],
]
],
[
[
"Exact match should override any already found matches that "
.
"are redirects to it"
,
'provision'
=>
[
// Another redirect to the same target as the exact match
// is low in the list
'Redirect Test Worse Result'
,
'Redirect test'
,
],
'query'
=>
'Redirect Test'
,
'results'
=>
[
// Found redirect is pulled to the top and exact match isn't
// added
'Redirect Test'
,
'Redirect Test Worse Result'
,
'Redirect test'
,
],
]
],
[
[
"Extra results must not be returned"
,
'provision'
=>
[
'Example'
,
'Example Bar'
,
'Example Foo'
,
'Example Foo/Bar'
],
'query'
=>
'foo'
,
'results'
=>
[
'Example'
,
'Example Bar'
,
'Example Foo'
,
],
]
],
];
}
/**
* @dataProvider provideSearchBackend
* @covers \PrefixSearch::searchBackend
*/
public
function
testSearchBackend
(
array
$case
)
{
$search
=
$this
->
mockSearchWithResults
(
$case
[
'provision'
]
);
$results
=
$search
->
completionSearch
(
$case
[
'query'
]
);
$results
=
$results
->
map
(
static
function
(
SearchSuggestion
$s
)
{
return
$s
->
getText
();
}
);
$this
->
assertEquals
(
$case
[
'results'
],
$results
,
$case
[
0
]
);
}
public
static
function
paginationProvider
()
{
$res
=
[
'Example'
,
'Example Bar'
,
'Example Foo'
,
'Example Foo/Bar'
];
return
[
'With less than requested results no pagination'
=>
[
false
,
array_slice
(
$res
,
0
,
2
),
],
'With same as requested results no pagination'
=>
[
false
,
array_slice
(
$res
,
0
,
3
),
],
'With extra result returned offer pagination'
=>
[
true
,
$res
,
],
];
}
/**
* @dataProvider paginationProvider
* @covers \SearchSuggestionSet::hasMoreResults
*/
public
function
testPagination
(
$hasMoreResults
,
$provision
)
{
$search
=
$this
->
mockSearchWithResults
(
$provision
);
$results
=
$search
->
completionSearch
(
'irrelevant'
);
$this
->
assertEquals
(
$hasMoreResults
,
$results
->
hasMoreResults
()
);
}
private
function
mockSearchWithResults
(
$titleStrings
,
$limit
=
3
)
{
$search
=
$this
->
getMockBuilder
(
SearchEngine
::
class
)
->
onlyMethods
(
[
'completionSearchBackend'
]
)->
getMock
();
$return
=
SearchSuggestionSet
::
fromStrings
(
$titleStrings
);
$search
->
method
(
'completionSearchBackend'
)
->
willReturn
(
$return
);
$search
->
setLimitOffset
(
$limit
);
return
$search
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, Oct 3, 20:14 (3 d, 12 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
fd/25/da7189c9a38f355abf14dffe647e
Default Alt Text
SearchEnginePrefixTest.php (9 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment