From c16704c33a278b729c11922916445b41ce05253b Mon Sep 17 00:00:00 2001 From: Max Semenik Date: Fri, 5 Oct 2018 17:56:53 -0700 Subject: [PATCH] Display SVGs in target language Previously, they were always displayed in defult language unless forced explicitly in wikitext, e.g. [[File:Foo.svg|lang=ru]]. This change adds a feature flag that would enable always trying to display in page language. * If enabled, Parser will pass a new parameter - 'pagelang' - to the media handler. * SvgHandler uses page language when determining what language to render the image in. * 'pagelang' can always be overridden by 'lang'. * If no translation in page language is available, the default language (English) will be used for thumbnail URLs, to prevent cluttering media storage and HTTP caches with useless copies. Performance: this requires accessing image's metadata during parsing. My testing indicates there were no code path where this wasn't the case already, so no performance hit is expected, however we should still keep an eye on page save performance. Bug: T205040 Change-Id: I348840ef405e1370cc0c17d69051bce30153c9c0 --- RELEASE-NOTES-1.33 | 3 +- includes/DefaultSettings.php | 10 + includes/Linker.php | 1 + includes/media/ImageHandler.php | 2 +- includes/media/SvgHandler.php | 50 ++- includes/parser/Parser.php | 5 + tests/parser/ParserTestRunner.php | 14 +- tests/parser/parserTests.txt | 26 +- tests/phpunit/includes/media/SVGTest.php | 113 ------ .../phpunit/includes/media/SvgHandlerTest.php | 367 ++++++++++++++++++ 10 files changed, 466 insertions(+), 125 deletions(-) delete mode 100644 tests/phpunit/includes/media/SVGTest.php create mode 100644 tests/phpunit/includes/media/SvgHandlerTest.php diff --git a/RELEASE-NOTES-1.33 b/RELEASE-NOTES-1.33 index 3e7e49684a..5ed9d5ad2b 100644 --- a/RELEASE-NOTES-1.33 +++ b/RELEASE-NOTES-1.33 @@ -11,7 +11,8 @@ production. * $wgEnablePartialBlocks – This enables the Partial Blocks feature, which gives accounts with block permissions the ability to block users, IPs, and IP ranges from editing specific pages, while allowing them to edit the rest of the wiki. -* … +* $wgMediaInTargetLanguage – whether multilingual images should be dispalyed in + the current parse language where available. ==== Changed configuration ==== * … diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 82dbecfada..9c26a285e1 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1225,6 +1225,16 @@ $wgSVGMetadataCutoff = 262144; */ $wgAllowTitlesInSVG = false; +/** + * Whether thumbnails should be generated in target language (usually, same as + * page language), if available. + * Currently, applies only to SVG images that use the systemLanguage attribute + * to specify text language. + * + * @since 1.33 + */ +$wgMediaInTargetLanguage = false; + /** * The maximum number of pixels a source image can have if it is to be scaled * down by a scaler that requires the full source image to be decompressed diff --git a/includes/Linker.php b/includes/Linker.php index a3fba831d4..1d1ad0696f 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -289,6 +289,7 @@ class Linker { * link-title Title object to link to * link-target Value for the target attribute, only with link-url * no-link Boolean, suppress description link + * targetlang (optional) Target language code, see Parser::getTargetLanguage() * * @param array $handlerParams Associative array of media handler parameters, to be passed * to transform(). Typical keys are "width" and "page". diff --git a/includes/media/ImageHandler.php b/includes/media/ImageHandler.php index a0a160321c..e88c1b0a3f 100644 --- a/includes/media/ImageHandler.php +++ b/includes/media/ImageHandler.php @@ -83,7 +83,7 @@ abstract class ImageHandler extends MediaHandler { * @param array &$params * @return bool */ - function normaliseParams( $image, &$params ) { + public function normaliseParams( $image, &$params ) { $mimeType = $image->getMimeType(); if ( !isset( $params['width'] ) ) { diff --git a/includes/media/SvgHandler.php b/includes/media/SvgHandler.php index a9c7b4fe89..e3057f4537 100644 --- a/includes/media/SvgHandler.php +++ b/includes/media/SvgHandler.php @@ -136,6 +136,16 @@ class SvgHandler extends ImageHandler { return null; } + /** + * Determines render language from image parameters + * + * @param array $params + * @return string + */ + protected function getLanguageFromParams( array $params ) { + return $params['lang'] ?? $params['targetlang'] ?? 'en'; + } + /** * What language to render file in if none selected * @@ -160,11 +170,27 @@ class SvgHandler extends ImageHandler { * @param array &$params * @return bool */ - function normaliseParams( $image, &$params ) { - global $wgSVGMaxSize; - if ( !parent::normaliseParams( $image, $params ) ) { - return false; + public function normaliseParams( $image, &$params ) { + if ( parent::normaliseParams( $image, $params ) ) { + $params = $this->normaliseParamsInternal( $image, $params ); + return true; } + + return false; + } + + /** + * Code taken out of normaliseParams() for testability + * + * @since 1.33 + * + * @param File $image + * @param array $params + * @return array Modified $params + */ + protected function normaliseParamsInternal( $image, $params ) { + global $wgSVGMaxSize; + # Don't make an image bigger than wgMaxSVGSize on the smaller side if ( $params['physicalWidth'] <= $params['physicalHeight'] ) { if ( $params['physicalWidth'] > $wgSVGMaxSize ) { @@ -181,8 +207,15 @@ class SvgHandler extends ImageHandler { $params['physicalHeight'] = $wgSVGMaxSize; } } + // To prevent the proliferation of thumbnails in languages not present in SVGs, unless + // explicitly forced by user. + if ( isset( $params['targetlang'] ) ) { + if ( !$image->getMatchedLanguage( $params['targetlang'] ) ) { + unset( $params['targetlang'] ); + } + } - return true; + return $params; } /** @@ -201,7 +234,7 @@ class SvgHandler extends ImageHandler { $clientHeight = $params['height']; $physicalWidth = $params['physicalWidth']; $physicalHeight = $params['physicalHeight']; - $lang = $params['lang'] ?? $this->getDefaultRenderLanguage( $image ); + $lang = $this->getLanguageFromParams( $params ); if ( $flags & self::TRANSFORM_LATER ) { return new ThumbnailImage( $image, $dstUrl, $dstPath, $params ); @@ -531,8 +564,9 @@ class SvgHandler extends ImageHandler { */ public function makeParamString( $params ) { $lang = ''; - if ( isset( $params['lang'] ) && $params['lang'] !== 'en' ) { - $lang = 'lang' . strtolower( $params['lang'] ) . '-'; + $code = $this->getLanguageFromParams( $params ); + if ( $code !== 'en' ) { + $lang = 'lang' . strtolower( $code ) . '-'; } if ( !isset( $params['width'] ) ) { return false; diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 3509200c99..721d1fb5bf 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -5258,6 +5258,8 @@ class Parser { # * bottom # * text-bottom + global $wgMediaInTargetLanguage; + # Protect LanguageConverter markup when splitting into parts $parts = StringUtils::delimiterExplode( '-{', '}-', '|', $options, true /* allow nesting */ @@ -5415,6 +5417,9 @@ class Parser { # Use the "caption" for the tooltip text $params['frame']['title'] = $this->stripAltText( $caption, $holders ); } + if ( $wgMediaInTargetLanguage ) { + $params['handler']['targetlang'] = $this->getTargetLanguage()->getCode(); + } Hooks::run( 'ParserMakeImageParams', [ $title, $file, &$params, $this ] ); diff --git a/tests/parser/ParserTestRunner.php b/tests/parser/ParserTestRunner.php index 1f3183f3ed..5c4c48c4d4 100644 --- a/tests/parser/ParserTestRunner.php +++ b/tests/parser/ParserTestRunner.php @@ -300,6 +300,7 @@ class ParserTestRunner { $setup['wgHtml5'] = true; $setup['wgDisableLangConversion'] = false; $setup['wgDisableTitleConversion'] = false; + $setup['wgMediaInTargetLanguage'] = false; // "extra language links" // see https://gerrit.wikimedia.org/r/111390 @@ -1113,6 +1114,7 @@ class ParserTestRunner { + [ 'ISBN' => true, 'PMID' => true, 'RFC' => true ], // Test with legacy encoding by default until HTML5 is very stable and default 'wgFragmentMode' => [ 'legacy' ], + 'wgMediaInTargetLanguage' => self::getOptionValue( 'wgMediaInTargetLanguage', $opts, false ), ]; $nonIncludable = self::getOptionValue( 'wgNonincludableNamespaces', $opts, false ); @@ -1393,7 +1395,17 @@ class ParserTestRunner { 'bits' => 0, 'media_type' => MEDIATYPE_DRAWING, 'mime' => 'image/svg+xml', - 'metadata' => serialize( [] ), + 'metadata' => serialize( [ + 'version' => SvgHandler::SVG_METADATA_VERSION, + 'width' => 240, + 'height' => 180, + 'originalWidth' => '100%', + 'originalHeight' => '100%', + 'translations' => [ + 'en' => SVGReader::LANG_FULL_MATCH, + 'ru' => SVGReader::LANG_FULL_MATCH, + ], + ] ), 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ), 'fileExists' => true ], $this->db->timestamp( '20010115123500' ), $user ); diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index bbd9ecbe99..d836111abb 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -37,7 +37,7 @@ # You can also set the following parser properties via test options: # wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel, # wgLinkHolderBatchSize, wgRawHtml, wgInterwikiMagic, -# wgEnableMagicLinks +# wgEnableMagicLinks, wgMediaInTargetLanguage # # For testing purposes, temporary articles can created: # !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle @@ -15370,6 +15370,30 @@ parsoid=wt2html,wt2wt,html2html
lang=invalid:language:code
!! end +!! test +SVG thumbnails in page language +!! options +language=ru +wgMediaInTargetLanguage = true +!! wikitext +[[File:Foobar.svg]] [[File:Foobar.svg|lang=en]] +!! html/php +

Foobar.svg Foobar.svg +

+!! end + +!! test +SVG thumbnails in page language not present in the file +!! options +language=de +wgMediaInTargetLanguage = true +!! wikitext +[[File:Foobar.svg]] [[File:Foobar.svg|lang=ru]] +!! html/php +

Foobar.svg Foobar.svg +

+!! end + !! test T3887: A ISBN with a thumbnail !! wikitext diff --git a/tests/phpunit/includes/media/SVGTest.php b/tests/phpunit/includes/media/SVGTest.php deleted file mode 100644 index b68dd0ee0a..0000000000 --- a/tests/phpunit/includes/media/SVGTest.php +++ /dev/null @@ -1,113 +0,0 @@ -filePath = __DIR__ . '/../../data/media/'; - - $this->setMwGlobals( 'wgShowEXIF', true ); - - $this->handler = new SvgHandler; - } - - /** - * @param string $filename - * @param array $expected The expected independent metadata - * @dataProvider providerGetIndependentMetaArray - * @covers SvgHandler::getCommonMetaArray - */ - public function testGetIndependentMetaArray( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/svg+xml' ); - $res = $this->handler->getCommonMetaArray( $file ); - - $this->assertEquals( $res, $expected ); - } - - public static function providerGetIndependentMetaArray() { - return [ - [ 'Tux.svg', [ - 'ObjectName' => 'Tux', - 'ImageDescription' => - 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg', - ] ], - [ 'Wikimedia-logo.svg', [] ] - ]; - } - - /** - * @param string $userPreferredLanguage - * @param array $svgLanguages - * @param string $expectedMatch - * @dataProvider providerGetMatchedLanguage - * @covers SvgHandler::getMatchedLanguage - */ - public function testGetMatchedLanguage( $userPreferredLanguage, $svgLanguages, $expectedMatch ) { - $match = $this->handler->getMatchedLanguage( $userPreferredLanguage, $svgLanguages ); - $this->assertEquals( $expectedMatch, $match ); - } - - public function providerGetMatchedLanguage() { - return [ - 'no match' => [ - 'userPreferredLanguage' => 'en', - 'svgLanguages' => [ 'de-DE', 'zh', 'ga', 'fr', 'sr-Latn-ME' ], - 'expectedMatch' => null, - ], - 'no subtags' => [ - 'userPreferredLanguage' => 'en', - 'svgLanguages' => [ 'de', 'zh', 'en', 'fr' ], - 'expectedMatch' => 'en', - ], - 'user no subtags, svg 1 subtag' => [ - 'userPreferredLanguage' => 'en', - 'svgLanguages' => [ 'de-DE', 'en-GB', 'en-US', 'fr' ], - 'expectedMatch' => 'en-GB', - ], - 'user no subtags, svg >1 subtag' => [ - 'userPreferredLanguage' => 'sr', - 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'en-US', 'fr' ], - 'expectedMatch' => 'sr-Cyrl-BA', - ], - 'user 1 subtag, svg no subtags' => [ - 'userPreferredLanguage' => 'en-US', - 'svgLanguages' => [ 'de', 'en', 'en', 'fr' ], - 'expectedMatch' => null, - ], - 'user 1 subtag, svg 1 subtag' => [ - 'userPreferredLanguage' => 'en-US', - 'svgLanguages' => [ 'de-DE', 'en-GB', 'en-US', 'fr' ], - 'expectedMatch' => 'en-US', - ], - 'user 1 subtag, svg >1 subtag' => [ - 'userPreferredLanguage' => 'sr-Latn', - 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'fr' ], - 'expectedMatch' => 'sr-Latn-ME', - ], - 'user >1 subtag, svg >1 subtag' => [ - 'userPreferredLanguage' => 'sr-Latn-ME', - 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'en-US', 'fr' ], - 'expectedMatch' => 'sr-Latn-ME', - ], - 'user >1 subtag, svg <=1 subtag' => [ - 'userPreferredLanguage' => 'sr-Latn-ME', - 'svgLanguages' => [ 'de-DE', 'sr-Cyrl', 'sr-Latn', 'en-US', 'fr' ], - 'expectedMatch' => null, - ], - 'ensure case-insensitive' => [ - 'userPreferredLanguage' => 'sr-latn', - 'svgLanguages' => [ 'de-DE', 'sr-Cyrl', 'sr-Latn-ME', 'en-US', 'fr' ], - 'expectedMatch' => 'sr-Latn-ME', - ], - ]; - } -} diff --git a/tests/phpunit/includes/media/SvgHandlerTest.php b/tests/phpunit/includes/media/SvgHandlerTest.php new file mode 100644 index 0000000000..9c98ada43b --- /dev/null +++ b/tests/phpunit/includes/media/SvgHandlerTest.php @@ -0,0 +1,367 @@ +filePath = __DIR__ . '/../../data/media/'; + $this->setMwGlobals( 'wgShowEXIF', true ); + + $file = $this->dataFile( $filename, 'image/svg+xml' ); + $handler = new SvgHandler(); + $res = $handler->getCommonMetaArray( $file ); + + self::assertEquals( $res, $expected ); + } + + public static function provideGetIndependentMetaArray() { + return [ + [ 'Tux.svg', [ + 'ObjectName' => 'Tux', + 'ImageDescription' => + 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg', + ] ], + [ 'Wikimedia-logo.svg', [] ] + ]; + } + + /** + * @covers SvgHandler::getMatchedLanguage() + * @dataProvider provideGetMatchedLanguage + * + * @param string $userPreferredLanguage + * @param array $svgLanguages + * @param string $expectedMatch + */ + public function testGetMatchedLanguage( $userPreferredLanguage, $svgLanguages, $expectedMatch ) { + $handler = new SvgHandler(); + $match = $handler->getMatchedLanguage( $userPreferredLanguage, $svgLanguages ); + self::assertEquals( $expectedMatch, $match ); + } + + public function provideGetMatchedLanguage() { + return [ + 'no match' => [ + 'userPreferredLanguage' => 'en', + 'svgLanguages' => [ 'de-DE', 'zh', 'ga', 'fr', 'sr-Latn-ME' ], + 'expectedMatch' => null, + ], + 'no subtags' => [ + 'userPreferredLanguage' => 'en', + 'svgLanguages' => [ 'de', 'zh', 'en', 'fr' ], + 'expectedMatch' => 'en', + ], + 'user no subtags, svg 1 subtag' => [ + 'userPreferredLanguage' => 'en', + 'svgLanguages' => [ 'de-DE', 'en-GB', 'en-US', 'fr' ], + 'expectedMatch' => 'en-GB', + ], + 'user no subtags, svg >1 subtag' => [ + 'userPreferredLanguage' => 'sr', + 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'en-US', 'fr' ], + 'expectedMatch' => 'sr-Cyrl-BA', + ], + 'user 1 subtag, svg no subtags' => [ + 'userPreferredLanguage' => 'en-US', + 'svgLanguages' => [ 'de', 'en', 'en', 'fr' ], + 'expectedMatch' => null, + ], + 'user 1 subtag, svg 1 subtag' => [ + 'userPreferredLanguage' => 'en-US', + 'svgLanguages' => [ 'de-DE', 'en-GB', 'en-US', 'fr' ], + 'expectedMatch' => 'en-US', + ], + 'user 1 subtag, svg >1 subtag' => [ + 'userPreferredLanguage' => 'sr-Latn', + 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'fr' ], + 'expectedMatch' => 'sr-Latn-ME', + ], + 'user >1 subtag, svg >1 subtag' => [ + 'userPreferredLanguage' => 'sr-Latn-ME', + 'svgLanguages' => [ 'de-DE', 'sr-Cyrl-BA', 'sr-Latn-ME', 'en-US', 'fr' ], + 'expectedMatch' => 'sr-Latn-ME', + ], + 'user >1 subtag, svg <=1 subtag' => [ + 'userPreferredLanguage' => 'sr-Latn-ME', + 'svgLanguages' => [ 'de-DE', 'sr-Cyrl', 'sr-Latn', 'en-US', 'fr' ], + 'expectedMatch' => null, + ], + 'ensure case-insensitive' => [ + 'userPreferredLanguage' => 'sr-latn', + 'svgLanguages' => [ 'de-DE', 'sr-Cyrl', 'sr-Latn-ME', 'en-US', 'fr' ], + 'expectedMatch' => 'sr-Latn-ME', + ], + ]; + } + + /** + * @covers \SvgHandler::makeParamString() + * @dataProvider provideMakeParamString + * + * @param array $params + * @param string $expected + * @param string $message + */ + public function testMakeParamString( array $params, $expected, $message = '' ) { + $handler = new SvgHandler(); + self::assertEquals( $expected, $handler->makeParamString( $params ), $message ); + } + + public function provideMakeParamString() { + return [ + [ + [], + false, + "Don't thumbnail without knowing width" + ], + [ + [ 'lang' => 'ru' ], + false, + "Don't thumbnail without knowing width, even with lang" + ], + [ + [ 'width' => 123, ], + '123px', + 'Width in thumb' + ], + [ + [ 'width' => 123, 'lang' => 'en' ], + '123px', + 'Ignore lang=en' + ], + [ + [ 'width' => 123, 'targetlang' => 'en' ], + '123px', + 'Ignore targetlang=en' + ], + [ + [ 'width' => 123, 'lang' => 'en', 'targetlang' => 'ru' ], + '123px', + "lang should override targetlang even of it's in English" + ], + [ + [ 'width' => 123, 'targetlang' => 'en' ], + '123px', + 'Ignore targetlang=en' + ], + [ + [ 'width' => 123, 'lang' => 'en', 'targetlang' => 'en' ], + '123px', + 'Ignore lang=targetlang=en' + ], + [ + [ 'width' => 123, 'lang' => 'ru' ], + 'langru-123px', + 'Include lang in thumb' + ], + [ + [ 'width' => 123, 'targetlang' => 'ru' ], + 'langru-123px', + 'Include targetlang in thumb' + ], + [ + [ 'width' => 123, 'lang' => 'fr', 'targetlang' => 'sq' ], + 'langfr-123px', + 'lang should override targetlang' + ], + ]; + } + + /** + * @covers SvgHandler::normaliseParamsInternal() + * @dataProvider provideNormaliseParamsInternal + * + * @param $message + * @param int $width + * @param int $height + * @param array $params + * @param array $paramsExpected + */ + public function testNormaliseParamsInternal( $message, + $width, + $height, + array $params, + array $paramsExpected = null + ) { + $this->setMwGlobals( 'wgSVGMaxSize', 1000 ); + + /** @var SvgHandler $handler */ + $handler = TestingAccessWrapper::newFromObject( new SvgHandler() ); + + $file = $this->getMockBuilder( File::class ) + ->disableOriginalConstructor() + ->setMethods( [ 'getWidth', 'getHeight', 'getMetadata', 'getHandler' ] ) + ->getMock(); + + $file->method( 'getWidth' ) + ->willReturn( $width ); + $file->method( 'getHeight' ) + ->willReturn( $height ); + $file->method( 'getMetadata' ) + ->willReturn( serialize( [ + 'version' => SvgHandler::SVG_METADATA_VERSION, + 'translations' => [ + 'en' => SVGReader::LANG_FULL_MATCH, + 'ru' => SVGReader::LANG_FULL_MATCH, + ], + ] ) ); + $file->method( 'getHandler' ) + ->willReturn( $handler ); + + /** @var File $file */ + $params = $handler->normaliseParamsInternal( $file, $params ); + self::assertEquals( $paramsExpected, $params, $message ); + } + + public function provideNormaliseParamsInternal() { + return [ + [ + 'No need to change anything', + 400, 500, + [ 'physicalWidth' => 400, 'physicalHeight' => 500 ], + [ 'physicalWidth' => 400, 'physicalHeight' => 500 ], + ], + [ + 'Resize horizontal image', + 2000, 1600, + [ 'physicalWidth' => 2000, 'physicalHeight' => 1600, 'page' => 0 ], + [ 'physicalWidth' => 1250, 'physicalHeight' => 1000, 'page' => 0 ], + ], + [ + 'Resize vertical image', + 1600, 2000, + [ 'physicalWidth' => 1600, 'physicalHeight' => 2000, 'page' => 0 ], + [ 'physicalWidth' => 1000, 'physicalHeight' => 1250, 'page' => 0 ], + ], + [ + 'Preserve targetlang present in the image', + 400, 500, + [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ], + [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ], + ], + [ + 'Preserve targetlang present in the image 2', + 400, 500, + [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ], + [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'en' ], + ], + [ + 'Remove targetlang not present in the image', + 400, 500, + [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'de' ], + [ 'physicalWidth' => 400, 'physicalHeight' => 500 ], + ], + [ + 'Remove targetlang not present in the image 2', + 400, 500, + [ 'physicalWidth' => 400, 'physicalHeight' => 500, 'targetlang' => 'ru-UA' ], + [ 'physicalWidth' => 400, 'physicalHeight' => 500 ], + ], + ]; + } + + /** + * @covers \SvgHandler::isEnabled() + * @dataProvider provideIsEnabled + * + * @param string $converter + * @param bool $expected + */ + public function testIsEnabled( $converter, $expected ) { + $this->setMwGlobals( 'wgSVGConverter', $converter ); + + $handler = new SvgHandler(); + self::assertEquals( $handler->isEnabled(), $expected ); + } + + public function provideIsEnabled() { + return [ + [ 'ImageMagick', true ], + [ 'sodipodi', true ], + [ 'invalid', false ], + ]; + } + + /** + * @covers \SvgHandler::getAvailableLanguages() + * @dataProvider provideAvailableLanguages + * + * @param array $metadata + * @param array $expected + */ + public function testGetAvailableLanguages( array $metadata, array $expected ) { + $metadata['version'] = SvgHandler::SVG_METADATA_VERSION; + $file = $this->getMockBuilder( File::class ) + ->disableOriginalConstructor() + ->setMethods( [ 'getMetadata' ] ) + ->getMock(); + $file->method( 'getMetadata' ) + ->willReturn( serialize( $metadata ) ); + + $handler = new SvgHandler(); + /** @var File $file */ + self::assertEquals( $expected, $handler->getAvailableLanguages( $file ) ); + } + + public function provideAvailableLanguages() { + return [ + [ [], [] ], + [ [ 'translations' => [] ], [] ], + [ + [ + 'translations' => [ + 'ru-RU' => SVGReader::LANG_PREFIX_MATCH + ] + ], + [], + ], + [ + [ + 'translations' => [ + 'en' => SVGReader::LANG_FULL_MATCH, + 'ru-RU' => SVGReader::LANG_PREFIX_MATCH, + 'ru' => SVGReader::LANG_FULL_MATCH, + 'fr-CA' => SVGReader::LANG_PREFIX_MATCH, + ], + ], + [ 'en', 'ru' ], + ], + ]; + } + + /** + * @covers SvgHandler::getLanguageFromParams() + * @dataProvider provideGetLanguageFromParams + * + * @param array $params + * @param string $expected + * @param string $message + */ + public function testGetLanguageFromParams( array $params, $expected, $message ) { + /** @var SvgHandler $handler */ + $handler = TestingAccessWrapper::newFromObject( new SvgHandler() ); + self::assertEquals( $expected, $handler->getLanguageFromParams( $params ), $message ); + } + + public function provideGetLanguageFromParams() { + return [ + [ [], 'en', 'Default no language to en' ], + [ [ 'preserve' => 'this' ], 'en', 'Default no language to en 2' ], + [ [ 'preserve' => 'this', 'lang' => 'ru' ], 'ru', 'Language from lang' ], + [ [ 'lang' => 'ru' ], 'ru', 'Language from lang 2' ], + [ [ 'targetlang' => 'fr' ], 'fr', 'Language from targetlang' ], + [ [ 'lang' => 'fr', 'targetlang' => 'de' ], 'fr', 'lang overrides targetlang' ], + ]; + } +} -- 2.20.1