1<?php 2 3/** 4 * @group ResourceLoader 5 * @covers ResourceLoaderImage 6 */ 7class ResourceLoaderImageTest extends MediaWikiUnitTestCase { 8 9 private $imagesPath; 10 11 protected function setUp(): void { 12 parent::setUp(); 13 $this->imagesPath = __DIR__ . '/../../../data/resourceloader'; 14 } 15 16 protected function getTestImage( $name ) { 17 $options = ResourceLoaderImageModuleTest::$commonImageData[$name]; 18 $fileDescriptor = is_string( $options ) ? $options : $options['file']; 19 $allowedVariants = ( is_array( $options ) && isset( $options['variants'] ) ) ? 20 $options['variants'] : []; 21 $variants = array_fill_keys( $allowedVariants, [ 'color' => 'red' ] ); 22 return new ResourceLoaderImageTestable( 23 $name, 24 'test', 25 $fileDescriptor, 26 $this->imagesPath, 27 $variants 28 ); 29 } 30 31 public static function provideGetPath() { 32 return [ 33 [ 'abc', 'en', 'abc.gif' ], 34 [ 'abc', 'he', 'abc.gif' ], 35 [ 'def', 'en', 'def.svg' ], 36 [ 'def', 'he', 'def.svg' ], 37 [ 'ghi', 'en', 'ghi.svg' ], 38 [ 'ghi', 'he', 'jkl.svg' ], 39 [ 'mno', 'en', 'mno-ltr.svg' ], 40 [ 'mno', 'ar', 'mno-rtl.svg' ], 41 [ 'mno', 'he', 'mno-ltr.svg' ], 42 [ 'pqr', 'en', 'pqr-b.svg' ], 43 [ 'pqr', 'en-gb', 'pqr-b.svg' ], 44 [ 'pqr', 'de', 'pqr-f.svg' ], 45 [ 'pqr', 'de-formal', 'pqr-f.svg' ], 46 [ 'pqr', 'ar', 'pqr-f.svg' ], 47 [ 'pqr', 'fr', 'pqr-a.svg' ], 48 [ 'pqr', 'he', 'pqr-a.svg' ], 49 ]; 50 } 51 52 /** 53 * @dataProvider provideGetPath 54 */ 55 public function testGetPath( $imageName, $languageCode, $path ) { 56 static $dirMap = [ 57 'en' => 'ltr', 58 'en-gb' => 'ltr', 59 'de' => 'ltr', 60 'de-formal' => 'ltr', 61 'fr' => 'ltr', 62 'he' => 'rtl', 63 'ar' => 'rtl', 64 ]; 65 66 $image = $this->getTestImage( $imageName ); 67 $context = new DerivativeResourceLoaderContext( 68 $this->createMock( ResourceLoaderContext::class ) 69 ); 70 $context->setLanguage( $languageCode ); 71 $context->setDirection( $dirMap[$languageCode] ); 72 73 $this->assertEquals( $image->getPath( $context ), $this->imagesPath . '/' . $path ); 74 } 75 76 public function testGetExtension() { 77 $image = $this->getTestImage( 'def' ); 78 $this->assertSame( 'svg', $image->getExtension() ); 79 $this->assertSame( 'svg', $image->getExtension( 'original' ) ); 80 $this->assertSame( 'png', $image->getExtension( 'rasterized' ) ); 81 $image = $this->getTestImage( 'abc' ); 82 $this->assertSame( 'gif', $image->getExtension() ); 83 $this->assertSame( 'gif', $image->getExtension( 'original' ) ); 84 $this->assertSame( 'gif', $image->getExtension( 'rasterized' ) ); 85 } 86 87 public function testGetImageData() { 88 $context = $this->createMock( ResourceLoaderContext::class ); 89 90 $image = $this->getTestImage( 'def' ); 91 $data = file_get_contents( $this->imagesPath . '/def.svg' ); 92 $dataConstructive = file_get_contents( $this->imagesPath . '/def_variantize.svg' ); 93 $this->assertEquals( $image->getImageData( $context, null, 'original' ), $data ); 94 $this->assertEquals( 95 $image->getImageData( $context, 'destructive', 'original' ), 96 $dataConstructive 97 ); 98 // Stub, since we don't know if we even have a SVG handler, much less what exactly it'll output 99 $this->assertSame( 'RASTERIZESTUB', $image->getImageData( $context, null, 'rasterized' ) ); 100 101 $image = $this->getTestImage( 'abc' ); 102 $data = file_get_contents( $this->imagesPath . '/abc.gif' ); 103 $this->assertEquals( $image->getImageData( $context, null, 'original' ), $data ); 104 $this->assertEquals( $image->getImageData( $context, null, 'rasterized' ), $data ); 105 } 106 107 public function testMassageSvgPathdata() { 108 $image = $this->getTestImage( 'ghi' ); 109 $data = file_get_contents( $this->imagesPath . '/ghi.svg' ); 110 $dataMassaged = file_get_contents( $this->imagesPath . '/ghi_massage.svg' ); 111 $this->assertEquals( $image->massageSvgPathdata( $data ), $dataMassaged ); 112 } 113} 114 115class ResourceLoaderImageTestable extends ResourceLoaderImage { 116 private $mockFallbacks = [ 117 'en-gb' => [ 'en' ], 118 'de-formal' => [ 'de' ], 119 ]; 120 121 // Make some protected methods public 122 public function massageSvgPathdata( $svg ) { 123 return parent::massageSvgPathdata( $svg ); 124 } 125 126 // Stub, since we don't know if we even have a SVG handler, much less what exactly it'll output 127 public function rasterize( $svg ) { 128 return 'RASTERIZESTUB'; 129 } 130 131 protected function getLangFallbacks( string $code ): array { 132 return $this->mockFallbacks[$code] ?? []; 133 } 134} 135