Merge "Update wikimedia/normalized-exception to 2.1.1"
[mediawiki.git] / tests / phpunit / includes / search / SearchResultThumbnailProviderTest.php
blobff91c92848772359152b16a10d4b46039ed7fd27
1 <?php
3 use MediaWiki\Search\SearchResultThumbnailProvider;
4 use MediaWiki\Tests\Rest\Handler\MediaTestTrait;
5 use MediaWiki\Title\Title;
7 class SearchResultThumbnailProviderTest extends MediaWikiIntegrationTestCase {
8 use MediaTestTrait;
10 /**
11 * List of titles to create.
13 protected const TITLES = [
14 'file' => [
15 'id' => 1,
16 'text' => 'File_1.jpg',
17 'namespace' => NS_FILE,
19 'article_with_thumb' => [
20 'id' => 2,
21 'text' => 'Title_2',
22 'namespace' => NS_MAIN,
24 'article_without_thumb' => [
25 'id' => 3,
26 'text' => 'Title_3',
27 'namespace' => NS_MAIN,
31 /**
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;
40 /** @var Title[] */
41 private $titles = [];
43 public static function articleThumbnailsProvider(): array {
44 return [
45 // assert that NS_FILE pages provide their own file
47 // page ids
48 [ self::TITLES['file']['id'] ],
49 // thumbnail ids
50 [ self::TITLES['file']['id'] ],
51 // size
52 500
54 // assert that hook provides thumbnails for non-file pages
56 [ self::TITLES['article_with_thumb']['id'] ],
57 [ self::TITLES['file']['id'] ],
58 500
60 // assert thumbnail is missing when not NS_FILE & hook doesn't provide
62 [ self::TITLES['article_without_thumb']['id'] ],
63 [],
64 500
66 // assert that size is optional and defaults to something functional
68 [ self::TITLES['file']['id'] ],
69 [ self::TITLES['file']['id'] ],
70 null
75 public function setUp(): void {
76 parent::setUp();
78 // build mock titles based on descriptions in self::TITLES
79 $this->titles = [];
80 foreach ( self::TITLES as $data ) {
81 $this->titles[$data['id']] = $this->makeMockTitle(
82 $data['text'],
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(),
90 array_filter(
91 $this->titles,
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
103 continue;
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 ),
119 $size
123 ] );
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() );