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 private SearchResultThumbnailProvider
$thumbnailProvider;
43 public static function articleThumbnailsProvider(): array {
45 // assert that NS_FILE pages provide their own file
48 [ self
::TITLES
['file']['id'] ],
50 [ self
::TITLES
['file']['id'] ],
54 // assert that hook provides thumbnails for non-file pages
56 [ self
::TITLES
['article_with_thumb']['id'] ],
57 [ self
::TITLES
['file']['id'] ],
60 // assert thumbnail is missing when not NS_FILE & hook doesn't provide
62 [ self
::TITLES
['article_without_thumb']['id'] ],
66 // assert that size is optional and defaults to something functional
68 [ self
::TITLES
['file']['id'] ],
69 [ self
::TITLES
['file']['id'] ],
75 public function setUp(): void
{
78 // build mock titles based on descriptions in self::TITLES
80 foreach ( self
::TITLES
as $data ) {
81 $this->titles
[$data['id']] = $this->makeMockTitle(
83 [ 'id' => $data['id'], 'namespace' => $data['namespace'] ]
87 // compile a mock repo with all NS_FILE pages known in self::TITLES
88 $thumbnails = array_map(
89 static fn ( Title
$title ) => $title->getDBkey(),
92 static fn ( Title
$title ) => $title->inNamespace( NS_FILE
)
95 $mockRepoGroup = $this->makeMockRepoGroup( $thumbnails );
97 // create a hook that provides all thumbnails defined in HOOK_PROVIDED_THUMBNAILS_BY_ID
98 $hookContainer = $this->createHookContainer( [
99 'SearchResultProvideThumbnail' => function ( $pageIdentities, &$results, $size ) use ( $mockRepoGroup ) {
100 foreach ( self
::HOOK_PROVIDED_THUMBNAILS_BY_ID
as $pageId => $thumbnailPageId ) {
101 if ( !isset( $pageIdentities[$pageId] ) ) {
102 // skip this thumbnail, it was not requested
105 $articleTitle = $this->titles
[$pageId];
106 if ( !$articleTitle ) {
107 throw new InvalidArgumentException(
108 'self::HOOK_PROVIDED_THUMBNAILS_BY_ID key references a page missing from in self::TITLES'
111 $thumbnailTitle = $this->titles
[$thumbnailPageId];
112 if ( !$thumbnailTitle ) {
113 throw new InvalidArgumentException(
114 'self::HOOK_PROVIDED_THUMBNAILS_BY_ID value references a page missing from in self::TITLES'
117 $results[$pageId] = $this->thumbnailProvider
->buildSearchResultThumbnailFromFile(
118 $mockRepoGroup->findFile( $thumbnailTitle ),
124 $this->thumbnailProvider
= new SearchResultThumbnailProvider( $mockRepoGroup, $hookContainer );
128 * @dataProvider articleThumbnailsProvider
129 * @covers \MediaWiki\Search\SearchResultThumbnailProvider::getThumbnails
130 * @covers \MediaWiki\Search\SearchResultThumbnailProvider::buildSearchResultThumbnailFromFile
131 * @param int[] $pageIds
132 * @param int[] $thumbnailIds
133 * @param int|null $size
135 public function testGetThumbnails( array $pageIds, array $thumbnailIds, ?
int $size = null ) {
136 $pageIdentities = array_intersect_key( $this->titles
, array_fill_keys( $pageIds, null ) );
138 $thumbnails = $this->thumbnailProvider
->getThumbnails( $pageIdentities, $size );
140 // confirm that titles for which there is no thumbnail are missing
141 $missingThumbnails = array_diff_key( $pageIdentities, $thumbnails );
142 foreach ( $missingThumbnails as $pageId => $pageIdentity ) {
143 $this->assertArrayNotHasKey( $pageId, $thumbnails );
146 foreach ( $thumbnails as $pageId => $thumbnail ) {
147 // confirm thumbnail matches what we expect
148 $expectedName = $this->titles
[$pageId]->inNamespace( NS_FILE
)
149 ?
$this->titles
[$pageId]->getDBkey()
150 : $this->titles
[self
::HOOK_PROVIDED_THUMBNAILS_BY_ID
[$pageId]]->getDBkey();
151 $this->assertEquals( $expectedName, $thumbnail->getName() );
153 // confirm thumbnail dimensions
154 $expectedSize = $size ?? SearchResultThumbnailProvider
::THUMBNAIL_SIZE
;
155 $this->assertLessThanOrEqual( $expectedSize, $thumbnail->getWidth() );