Display SVGs in target language
[lhc/web/wiklou.git] / tests / phpunit / includes / media / SvgHandlerTest.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 /**
6 * @group Media
7 */
8 class SvgHandlerTest extends MediaWikiMediaTestCase {
9
10 /**
11 * @covers \SvgHandler::getCommonMetaArray()
12 * @dataProvider provideGetIndependentMetaArray
13 *
14 * @param string $filename
15 * @param array $expected The expected independent metadata
16 */
17 public function testGetIndependentMetaArray( $filename, $expected ) {
18 $this->filePath = __DIR__ . '/../../data/media/';
19 $this->setMwGlobals( 'wgShowEXIF', true );
20
21 $file = $this->dataFile( $filename, 'image/svg+xml' );
22 $handler = new SvgHandler();
23 $res = $handler->getCommonMetaArray( $file );
24
25 self::assertEquals( $res, $expected );
26 }
27
28 public static function provideGetIndependentMetaArray() {
29 return [
30 [ 'Tux.svg', [
31 'ObjectName' => 'Tux',
32 'ImageDescription' =>
33 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg',
34 ] ],
35 [ 'Wikimedia-logo.svg', [] ]
36 ];
37 }
38
39 /**
40 * @covers SvgHandler::getMatchedLanguage()
41 * @dataProvider provideGetMatchedLanguage
42 *
43 * @param string $userPreferredLanguage
44 * @param array $svgLanguages
45 * @param string $expectedMatch
46 */
47 public function testGetMatchedLanguage( $userPreferredLanguage, $svgLanguages, $expectedMatch ) {
48 $handler = new SvgHandler();
49 $match = $handler->getMatchedLanguage( $userPreferredLanguage, $svgLanguages );
50 self::assertEquals( $expectedMatch, $match );
51 }
52
53 public function provideGetMatchedLanguage() {
54 return [
55 'no match' => [
56 'userPreferredLanguage' => 'en',
57 'svgLanguages' => [ 'de-DE', 'zh', 'ga', 'fr', 'sr-Latn-ME' ],
58 'expectedMatch' => null,
59 ],
60 'no subtags' => [
61 'userPreferredLanguage' => 'en',
62 'svgLanguages' => [ 'de', 'zh', 'en', 'fr' ],
63 'expectedMatch' => 'en',
64 ],
65 'user no subtags, svg 1 subtag' => [
66 'userPreferredLanguage' => 'en',
67 'svgLanguages' => [ 'de-DE', 'en-GB', 'en-US', 'fr' ],
68 'expectedMatch' => 'en-GB',
69 ],
70 'user no subtags, svg >1 subtag' => [
71 'userPreferredLanguage' => 'sr',
72 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'en-US', 'fr' ],
73 'expectedMatch' => 'sr-Cyrl-BA',
74 ],
75 'user 1 subtag, svg no subtags' => [
76 'userPreferredLanguage' => 'en-US',
77 'svgLanguages' => [ 'de', 'en', 'en', 'fr' ],
78 'expectedMatch' => null,
79 ],
80 'user 1 subtag, svg 1 subtag' => [
81 'userPreferredLanguage' => 'en-US',
82 'svgLanguages' => [ 'de-DE', 'en-GB', 'en-US', 'fr' ],
83 'expectedMatch' => 'en-US',
84 ],
85 'user 1 subtag, svg >1 subtag' => [
86 'userPreferredLanguage' => 'sr-Latn',
87 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'fr' ],
88 'expectedMatch' => 'sr-Latn-ME',
89 ],
90 'user >1 subtag, svg >1 subtag' => [
91 'userPreferredLanguage' => 'sr-Latn-ME',
92 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'en-US', 'fr' ],
93 'expectedMatch' => 'sr-Latn-ME',
94 ],
95 'user >1 subtag, svg <=1 subtag' => [
96 'userPreferredLanguage' => 'sr-Latn-ME',
97 'svgLanguages' => [ 'de-DE', 'sr-Cyrl', 'sr-Latn', 'en-US', 'fr' ],
98 'expectedMatch' => null,
99 ],
100 'ensure case-insensitive' => [
101 'userPreferredLanguage' => 'sr-latn',
102 'svgLanguages' => [ 'de-DE', 'sr-Cyrl', 'sr-Latn-ME', 'en-US', 'fr' ],
103 'expectedMatch' => 'sr-Latn-ME',
104 ],
105 ];
106 }
107
108 /**
109 * @covers \SvgHandler::makeParamString()
110 * @dataProvider provideMakeParamString
111 *
112 * @param array $params
113 * @param string $expected
114 * @param string $message
115 */
116 public function testMakeParamString( array $params, $expected, $message = '' ) {
117 $handler = new SvgHandler();
118 self::assertEquals( $expected, $handler->makeParamString( $params ), $message );
119 }
120
121 public function provideMakeParamString() {
122 return [
123 [
124 [],
125 false,
126 "Don't thumbnail without knowing width"
127 ],
128 [
129 [ 'lang' => 'ru' ],
130 false,
131 "Don't thumbnail without knowing width, even with lang"
132 ],
133 [
134 [ 'width' => 123, ],
135 '123px',
136 'Width in thumb'
137 ],
138 [
139 [ 'width' => 123, 'lang' => 'en' ],
140 '123px',
141 'Ignore lang=en'
142 ],
143 [
144 [ 'width' => 123, 'targetlang' => 'en' ],
145 '123px',
146 'Ignore targetlang=en'
147 ],
148 [
149 [ 'width' => 123, 'lang' => 'en', 'targetlang' => 'ru' ],
150 '123px',
151 "lang should override targetlang even of it's in English"
152 ],
153 [
154 [ 'width' => 123, 'targetlang' => 'en' ],
155 '123px',
156 'Ignore targetlang=en'
157 ],
158 [
159 [ 'width' => 123, 'lang' => 'en', 'targetlang' => 'en' ],
160 '123px',
161 'Ignore lang=targetlang=en'
162 ],
163 [
164 [ 'width' => 123, 'lang' => 'ru' ],
165 'langru-123px',
166 'Include lang in thumb'
167 ],
168 [
169 [ 'width' => 123, 'targetlang' => 'ru' ],
170 'langru-123px',
171 'Include targetlang in thumb'
172 ],
173 [
174 [ 'width' => 123, 'lang' => 'fr', 'targetlang' => 'sq' ],
175 'langfr-123px',
176 'lang should override targetlang'
177 ],
178 ];
179 }
180
181 /**
182 * @covers SvgHandler::normaliseParamsInternal()
183 * @dataProvider provideNormaliseParamsInternal
184 *
185 * @param $message
186 * @param int $width
187 * @param int $height
188 * @param array $params
189 * @param array $paramsExpected
190 */
191 public function testNormaliseParamsInternal( $message,
192 $width,
193 $height,
194 array $params,
195 array $paramsExpected = null
196 ) {
197 $this->setMwGlobals( 'wgSVGMaxSize', 1000 );
198
199 /** @var SvgHandler $handler */
200 $handler = TestingAccessWrapper::newFromObject( new SvgHandler() );
201
202 $file = $this->getMockBuilder( File::class )
203 ->disableOriginalConstructor()
204 ->setMethods( [ 'getWidth', 'getHeight', 'getMetadata', 'getHandler' ] )
205 ->getMock();
206
207 $file->method( 'getWidth' )
208 ->willReturn( $width );
209 $file->method( 'getHeight' )
210 ->willReturn( $height );
211 $file->method( 'getMetadata' )
212 ->willReturn( serialize( [
213 'version' => SvgHandler::SVG_METADATA_VERSION,
214 'translations' => [
215 'en' => SVGReader::LANG_FULL_MATCH,
216 'ru' => SVGReader::LANG_FULL_MATCH,
217 ],
218 ] ) );
219 $file->method( 'getHandler' )
220 ->willReturn( $handler );
221
222 /** @var File $file */
223 $params = $handler->normaliseParamsInternal( $file, $params );
224 self::assertEquals( $paramsExpected, $params, $message );
225 }
226
227 public function provideNormaliseParamsInternal() {
228 return [
229 [
230 'No need to change anything',
231 400, 500,
232 [ 'physicalWidth' => 400, 'physicalHeight' => 500 ],
233 [ 'physicalWidth' => 400, 'physicalHeight' => 500 ],
234 ],
235 [
236 'Resize horizontal image',
237 2000, 1600,
238 [ 'physicalWidth' => 2000, 'physicalHeight' => 1600, 'page' => 0 ],
239 [ 'physicalWidth' => 1250, 'physicalHeight' => 1000, 'page' => 0 ],
240 ],
241 [
242 'Resize vertical image',
243 1600, 2000,
244 [ 'physicalWidth' => 1600, 'physicalHeight' => 2000, 'page' => 0 ],
245 [ 'physicalWidth' => 1000, 'physicalHeight' => 1250, 'page' => 0 ],
246 ],
247 [
248 'Preserve targetlang present in the image',
249 400, 500,
250 [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ],
251 [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ],
252 ],
253 [
254 'Preserve targetlang present in the image 2',
255 400, 500,
256 [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ],
257 [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ],
258 ],
259 [
260 'Remove targetlang not present in the image',
261 400, 500,
262 [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'de' ],
263 [ 'physicalWidth' => 400, 'physicalHeight' => 500 ],
264 ],
265 [
266 'Remove targetlang not present in the image 2',
267 400, 500,
268 [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'ru-UA' ],
269 [ 'physicalWidth' => 400, 'physicalHeight' => 500 ],
270 ],
271 ];
272 }
273
274 /**
275 * @covers \SvgHandler::isEnabled()
276 * @dataProvider provideIsEnabled
277 *
278 * @param string $converter
279 * @param bool $expected
280 */
281 public function testIsEnabled( $converter, $expected ) {
282 $this->setMwGlobals( 'wgSVGConverter', $converter );
283
284 $handler = new SvgHandler();
285 self::assertEquals( $handler->isEnabled(), $expected );
286 }
287
288 public function provideIsEnabled() {
289 return [
290 [ 'ImageMagick', true ],
291 [ 'sodipodi', true ],
292 [ 'invalid', false ],
293 ];
294 }
295
296 /**
297 * @covers \SvgHandler::getAvailableLanguages()
298 * @dataProvider provideAvailableLanguages
299 *
300 * @param array $metadata
301 * @param array $expected
302 */
303 public function testGetAvailableLanguages( array $metadata, array $expected ) {
304 $metadata['version'] = SvgHandler::SVG_METADATA_VERSION;
305 $file = $this->getMockBuilder( File::class )
306 ->disableOriginalConstructor()
307 ->setMethods( [ 'getMetadata' ] )
308 ->getMock();
309 $file->method( 'getMetadata' )
310 ->willReturn( serialize( $metadata ) );
311
312 $handler = new SvgHandler();
313 /** @var File $file */
314 self::assertEquals( $expected, $handler->getAvailableLanguages( $file ) );
315 }
316
317 public function provideAvailableLanguages() {
318 return [
319 [ [], [] ],
320 [ [ 'translations' => [] ], [] ],
321 [
322 [
323 'translations' => [
324 'ru-RU' => SVGReader::LANG_PREFIX_MATCH
325 ]
326 ],
327 [],
328 ],
329 [
330 [
331 'translations' => [
332 'en' => SVGReader::LANG_FULL_MATCH,
333 'ru-RU' => SVGReader::LANG_PREFIX_MATCH,
334 'ru' => SVGReader::LANG_FULL_MATCH,
335 'fr-CA' => SVGReader::LANG_PREFIX_MATCH,
336 ],
337 ],
338 [ 'en', 'ru' ],
339 ],
340 ];
341 }
342
343 /**
344 * @covers SvgHandler::getLanguageFromParams()
345 * @dataProvider provideGetLanguageFromParams
346 *
347 * @param array $params
348 * @param string $expected
349 * @param string $message
350 */
351 public function testGetLanguageFromParams( array $params, $expected, $message ) {
352 /** @var SvgHandler $handler */
353 $handler = TestingAccessWrapper::newFromObject( new SvgHandler() );
354 self::assertEquals( $expected, $handler->getLanguageFromParams( $params ), $message );
355 }
356
357 public function provideGetLanguageFromParams() {
358 return [
359 [ [], 'en', 'Default no language to en' ],
360 [ [ 'preserve' => 'this' ], 'en', 'Default no language to en 2' ],
361 [ [ 'preserve' => 'this', 'lang' => 'ru' ], 'ru', 'Language from lang' ],
362 [ [ 'lang' => 'ru' ], 'ru', 'Language from lang 2' ],
363 [ [ 'targetlang' => 'fr' ], 'fr', 'Language from targetlang' ],
364 [ [ 'lang' => 'fr', 'targetlang' => 'de' ], 'fr', 'lang overrides targetlang' ],
365 ];
366 }
367 }