1<?php
2
3namespace PageImages\Tests\Hooks;
4
5use LocalFile;
6use MediaWiki\Page\PageIdentity;
7use MediaWiki\Page\PageIdentityValue;
8use MediaWikiTestCase;
9use PageImages\Hooks\SearchResultProvideThumbnailHookHandler;
10use PageImages\PageImages;
11use PageProps;
12use RepoGroup;
13use ThumbnailImage;
14
15/**
16 * @covers \PageImages\Hooks\SearchResultProvideThumbnailHookHandler
17 *
18 * @group PageImages
19 */
20class SearchResultProvideThumbnailHookHandlerTest extends MediaWikiTestCase {
21	/**
22	 * Creates mock object for LocalFile
23	 * @param int $size
24	 * @param LocalFile $file
25	 * @param string $thumbFilePath
26	 * @return ThumbnailImage
27	 */
28	private function getMockThumbnailImage(
29		int $size,
30		LocalFile $file,
31		$thumbFilePath
32	): ThumbnailImage {
33		$thumbnail = $this->getMockBuilder( ThumbnailImage::class )
34			->disableOriginalConstructor()
35			->onlyMethods( [
36				'getLocalCopyPath',
37				'getWidth',
38				'getHeight',
39				'getFile',
40				'getUrl'
41			] )
42			->getMock();
43
44			$thumbnail->expects( $this->once() )
45				->method( 'getLocalCopyPath' )
46				->willReturn( $thumbFilePath );
47
48			$thumbnail->expects( $this->once() )
49				->method( 'getUrl' )
50				->willReturn( 'https://example.org/test.url' );
51
52			$thumbnail->expects( $this->once() )
53				->method( 'getWidth' )
54				->willReturn( $size );
55
56			$thumbnail->expects( $this->once() )
57				->method( 'getHeight' )
58				->willReturn( $size );
59
60			$thumbnail->expects( $this->once() )
61				->method( 'getFile' )
62				->willReturn( $file );
63
64		return $thumbnail;
65	}
66
67	/**
68	 * Creates mock object for LocalFile
69	 * @param int $size
70	 * @param string $thumbFilePath
71	 * @return LocalFile
72	 */
73	private function getMockLocalFile( int $size, $thumbFilePath ): LocalFile {
74		$file = $this->getMockBuilder( LocalFile::class )
75			->disableOriginalConstructor()
76			->onlyMethods( [
77				'transform',
78				'getMimeType'
79			] )
80			->getMock();
81
82		$file->expects( $this->once() )
83			->method( 'transform' )
84			->with( [ 'width' => $size , 'height' => $size ] )
85			->willReturn( $this->getMockThumbnailImage( $size, $file, $thumbFilePath ) );
86
87		$file->expects( $this->once() )
88			->method( 'getMimeType' )
89			->willReturn( 'image/jpg' );
90
91		return $file;
92	}
93
94	public function testProvideThumbnail() {
95		$pageProps = $this->getMockBuilder( PageProps::class )
96			->disableOriginalConstructor()
97			->onlyMethods( [ 'getProperties' ] )
98			->getMock();
99
100		$pageIdentities = [
101			1 => new PageIdentityValue( 1, NS_MAIN, 'dbKey1', PageIdentity::LOCAL ),
102			2 => new PageIdentityValue( 2, NS_MAIN, 'dbKey2', PageIdentity::LOCAL ),
103			3 => new PageIdentityValue( 3, NS_FILE, 'dbKey3', PageIdentity::LOCAL ),
104			4 => new PageIdentityValue( 4, NS_FILE, 'dbKey4', PageIdentity::LOCAL )
105		];
106
107		$pageProps->expects( $this->once() )
108			->method( 'getProperties' )
109			->with(
110				$this->anything(),
111				PageImages::getPropNames( PageImages::LICENSE_ANY )
112			)->willReturn( [
113				1 => [
114					PageImages::getPropName( true ) => 'File1.jpg'
115				],
116				2 => [
117					PageImages::getPropName( true ) => 'File2_free.jpg',
118					PageImages::getPropName( false ) => 'File2_any.jpg'
119				] ] );
120
121		$repoGroup = $this->getMockBuilder( RepoGroup::class )
122			->disableOriginalConstructor()
123			->onlyMethods( [ 'findFile' ] )
124			->getMock();
125
126		$repoGroup->expects( $this->exactly( 4 ) )
127			->method( 'findFile' )
128			->withConsecutive( [ 'File1.jpg' ], [ 'File2_any.jpg' ], [ 'dbKey3' ], [ 'dbKey4' ] )
129			->willReturnOnConsecutiveCalls(
130				$this->getMockLocalFile(
131					SearchResultProvideThumbnailHookHandler::THUMBNAIL_SIZE,
132					__FILE__
133				),
134				null,
135				$this->getMockLocalFile(
136					SearchResultProvideThumbnailHookHandler::THUMBNAIL_SIZE,
137					false
138				),
139				null
140			);
141
142		$handler = new SearchResultProvideThumbnailHookHandler( $pageProps, $repoGroup );
143
144		$results = [ 1 => null, 2 => null, 3 => null, 4 => null ];
145		$handler->doSearchResultProvideThumbnail( $pageIdentities, $results );
146
147		$this->assertNull( $results[ 2 ] );
148		$this->assertNull( $results[ 4 ] );
149
150		$this->assertNotNull( $results[ 1 ] );
151		$this->assertSame( 'File1.jpg', $results[ 1 ]->getName() );
152		$this->assertSame(
153			SearchResultProvideThumbnailHookHandler::THUMBNAIL_SIZE,
154			$results[ 1 ]->getWidth()
155		);
156		$this->assertSame(
157			SearchResultProvideThumbnailHookHandler::THUMBNAIL_SIZE,
158			$results[ 1 ]->getHeight()
159		);
160		$this->assertGreaterThan( 0, $results[ 1 ]->getSize() );
161		$this->assertSame( 'https://example.org/test.url', $results[ 1 ]->getUrl() );
162
163		$this->assertNotNull( $results[ 3 ] );
164		$this->assertNull( $results[ 3 ]->getSize() );
165	}
166}
167