3 use MediaWiki\Search\SearchResultThumbnailProvider
;
4 use MediaWiki\Tests\Rest\Handler\MediaTestTrait
;
5 use MediaWiki\Title\Title
;
7 class SearchResultThumbnailProviderTest
extends MediaWikiIntegrationTestCase
{
11 * List of titles to create.
13 protected const TITLES
= [
16 'text' => 'File_1.jpg',
17 'namespace' => NS_FILE
,
19 'article_with_thumb' => [
22 'namespace' => NS_MAIN
,
24 'article_without_thumb' => [
27 'namespace' => NS_MAIN
,
32 * Map of page id to thumbnail page id, both of which are expected to be present in self::TITLES.
33 * This map will be used to build a mock response for the SearchResultProvideThumbnail hook.
35 protected const HOOK_PROVIDED_THUMBNAILS_BY_ID
= [
36 self
::TITLES
['article_with_thumb']['id'] => self
::TITLES
['file']['id'],
39 /** @var SearchResultThumbnailProvider */
40 private $thumbnailProvider;
45 public static function articleThumbnailsProvider(): array {
47 // assert that NS_FILE pages provide their own file
50 [ self
::TITLES
['file']['id'] ],
52 [ self
::TITLES
['file']['id'] ],
56 // assert that hook provides thumbnails for non-file pages
58 [ self
::TITLES
['article_with_thumb']['id'] ],
59 [ self
::TITLES
['file']['id'] ],
62 // assert thumbnail is missing when not NS_FILE & hook doesn't provide
64 [ self
::TITLES
['article_without_thumb']['id'] ],
68 // assert that size is optional and defaults to something functional
70 [ self
::TITLES
['file']['id'] ],
71 [ self
::TITLES
['file']['id'] ],
77 public function setUp(): void
{
80 // build mock titles based on descriptions in self::TITLES
82 foreach ( self
::TITLES
as $data ) {
83 $this->titles
[$data['id']] = $this->makeMockTitle(
85 [ 'id' => $data['id'], 'namespace' => $data['namespace'] ]
89 // compile a mock repo with all NS_FILE pages known in self::TITLES
90 $thumbnails = array_map(
91 static fn ( Title
$title ) => $title->getDBkey(),
94 static fn ( Title
$title ) => $title->inNamespace( NS_FILE
)
97 $mockRepoGroup = $this->makeMockRepoGroup( $thumbnails );
99 // create a hook that provides all thumbnails defined in HOOK_PROVIDED_THUMBNAILS_BY_ID
100 $hookContainer = $this->createHookContainer( [
101 'SearchResultProvideThumbnail' => function ( $pageIdentities, &$results, $size ) use ( $mockRepoGroup ) {
102 foreach ( self
::HOOK_PROVIDED_THUMBNAILS_BY_ID
as $pageId => $thumbnailPageId ) {
103 if ( !isset( $pageIdentities[$pageId] ) ) {
104 // skip this thumbnail, it was not requested
107 $articleTitle = $this->titles
[$pageId];
108 if ( !$articleTitle ) {
109 throw new InvalidArgumentException(
110 'self::HOOK_PROVIDED_THUMBNAILS_BY_ID key references a page missing from in self::TITLES'
113 $thumbnailTitle = $this->titles
[$thumbnailPageId];
114 if ( !$thumbnailTitle ) {
115 throw new InvalidArgumentException(
116 'self::HOOK_PROVIDED_THUMBNAILS_BY_ID value references a page missing from in self::TITLES'
119 $results[$pageId] = $this->thumbnailProvider
->buildSearchResultThumbnailFromFile(
120 $mockRepoGroup->findFile( $thumbnailTitle ),
126 $this->thumbnailProvider
= new SearchResultThumbnailProvider( $mockRepoGroup, $hookContainer );
130 * @dataProvider articleThumbnailsProvider
131 * @covers \MediaWiki\Search\SearchResultThumbnailProvider::getThumbnails
132 * @covers \MediaWiki\Search\SearchResultThumbnailProvider::buildSearchResultThumbnailFromFile
133 * @param int[] $pageIds
134 * @param int[] $thumbnailIds
135 * @param int|null $size
137 public function testGetThumbnails( array $pageIds, array $thumbnailIds, ?
int $size = null ) {
138 $pageIdentities = array_intersect_key( $this->titles
, array_fill_keys( $pageIds, null ) );
140 $thumbnails = $this->thumbnailProvider
->getThumbnails( $pageIdentities, $size );
142 // confirm that titles for which there is no thumbnail are missing
143 $missingThumbnails = array_diff_key( $pageIdentities, $thumbnails );
144 foreach ( $missingThumbnails as $pageId => $pageIdentity ) {
145 $this->assertArrayNotHasKey( $pageId, $thumbnails );
148 foreach ( $thumbnails as $pageId => $thumbnail ) {
149 // confirm thumbnail matches what we expect
150 $expectedName = $this->titles
[$pageId]->inNamespace( NS_FILE
)
151 ?
$this->titles
[$pageId]->getDBkey()
152 : $this->titles
[self
::HOOK_PROVIDED_THUMBNAILS_BY_ID
[$pageId]]->getDBkey();
153 $this->assertEquals( $expectedName, $thumbnail->getName() );
155 // confirm thumbnail dimensions
156 $expectedSize = $size ?? SearchResultThumbnailProvider
::THUMBNAIL_SIZE
;
157 $this->assertLessThanOrEqual( $expectedSize, $thumbnail->getWidth() );