1<?php
2
3/**
4 * @group Media
5 * @covers SVGReader
6 */
7class SVGReaderTest extends \MediaWikiIntegrationTestCase {
8
9	/**
10	 * @dataProvider provideSvgFiles
11	 */
12	public function testGetMetadata( $infile, $expected ) {
13		$this->assertMetadata( $infile, $expected );
14	}
15
16	/**
17	 * @dataProvider provideSvgFilesWithXMLMetadata
18	 */
19	public function testGetXMLMetadata( $infile, $expected ) {
20		$r = new XMLReader();
21		$this->assertMetadata( $infile, $expected );
22	}
23
24	/**
25	 * @dataProvider provideSvgUnits
26	 */
27	public function testScaleSVGUnit( $inUnit, $expected ) {
28		$this->assertEquals(
29			$expected,
30			SVGReader::scaleSVGUnit( $inUnit ),
31			'SVG unit conversion and scaling failure'
32		);
33	}
34
35	private function assertMetadata( $infile, $expected ) {
36		try {
37			$svgReader = new SVGReader( $infile );
38			$data = $svgReader->getMetadata();
39
40			$this->assertEquals( $expected, $data, 'SVG metadata extraction test' );
41		} catch ( MWException $e ) {
42			if ( $expected === false ) {
43				$this->assertTrue( true, 'SVG metadata extracted test (expected failure)' );
44			} else {
45				throw $e;
46			}
47		}
48	}
49
50	public static function provideSvgFiles() {
51		$base = __DIR__ . '/../../data/media';
52
53		return [
54			[
55				"$base/Wikimedia-logo.svg",
56				[
57					'width' => 1024,
58					'height' => 1024,
59					'originalWidth' => '1024',
60					'originalHeight' => '1024',
61					'translations' => [],
62				]
63			],
64			[
65				"$base/QA_icon.svg",
66				[
67					'width' => 60,
68					'height' => 60,
69					'originalWidth' => '60',
70					'originalHeight' => '60',
71					'translations' => [],
72				]
73			],
74			[
75				"$base/Gtk-media-play-ltr.svg",
76				[
77					'width' => 60,
78					'height' => 60,
79					'originalWidth' => '60.0000000',
80					'originalHeight' => '60.0000000',
81					'translations' => [],
82				]
83			],
84			[
85				"$base/Toll_Texas_1.svg",
86				// This file triggered T33719, needs entity expansion in the xmlns checks
87				[
88					'width' => 385,
89					'height' => 385,
90					'originalWidth' => '385',
91					'originalHeight' => '385.0004883',
92					'translations' => [],
93				]
94			],
95			[
96				"$base/Tux.svg",
97				[
98					'width' => 512,
99					'height' => 594,
100					'originalWidth' => '100%',
101					'originalHeight' => '100%',
102					'title' => 'Tux',
103					'translations' => [],
104					'description' => 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg',
105				]
106			],
107			[
108				"$base/Speech_bubbles.svg",
109				[
110					'width' => 627,
111					'height' => 461,
112					'originalWidth' => '17.7cm',
113					'originalHeight' => '13cm',
114					'translations' => [
115						'de' => SVGReader::LANG_FULL_MATCH,
116						'fr' => SVGReader::LANG_FULL_MATCH,
117						'nl' => SVGReader::LANG_FULL_MATCH,
118						'tlh-ca' => SVGReader::LANG_FULL_MATCH,
119						'tlh' => SVGReader::LANG_PREFIX_MATCH
120					],
121				]
122			],
123			[
124				"$base/Soccer_ball_animated.svg",
125				[
126					'width' => 150,
127					'height' => 150,
128					'originalWidth' => '150',
129					'originalHeight' => '150',
130					'animated' => true,
131					'translations' => []
132				],
133			],
134			[
135				"$base/comma_separated_viewbox.svg",
136				[
137					'width' => 512,
138					'height' => 594,
139					'originalWidth' => '100%',
140					'originalHeight' => '100%',
141					'translations' => []
142				],
143			],
144		];
145	}
146
147	public static function provideSvgFilesWithXMLMetadata() {
148		$base = __DIR__ . '/../../data/media';
149		// phpcs:disable Generic.Files.LineLength
150		$metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
151      <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
152        <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
153        <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
154      </ns4:Work>
155    </rdf:RDF>';
156		// phpcs:enable
157
158		$metadata = str_replace( "\r", '', $metadata ); // Windows compat
159		return [
160			[
161				"$base/US_states_by_total_state_tax_revenue.svg",
162				[
163					'height' => 593,
164					'metadata' => $metadata,
165					'width' => 959,
166					'originalWidth' => '958.69',
167					'originalHeight' => '592.78998',
168					'translations' => [],
169				]
170			],
171		];
172	}
173
174	public static function provideSvgUnits() {
175		return [
176			[ '1' , 1 ],
177			[ '1.1' , 1.1 ],
178			[ '0.1' , 0.1 ],
179			[ '.1' , 0.1 ],
180			[ '1e2' , 100 ],
181			[ '1E2' , 100 ],
182			[ '+1' , 1 ],
183			[ '-1' , -1 ],
184			[ '-1.1' , -1.1 ],
185			[ '1e+2' , 100 ],
186			[ '1e-2' , 0.01 ],
187			[ '10px' , 10 ],
188			[ '10pt' , 10 * 1.25 ],
189			[ '10pc' , 10 * 15 ],
190			[ '10mm' , 10 * 3.543307 ],
191			[ '10cm' , 10 * 35.43307 ],
192			[ '10in' , 10 * 90 ],
193			[ '10em' , 10 * 16 ],
194			[ '10ex' , 10 * 12 ],
195			[ '10%' , 51.2 ],
196			[ '10 px' , 10 ],
197			// Invalid values
198			[ '1e1.1', 10 ],
199			[ '10bp', 10 ],
200			[ 'p10', null ],
201		];
202	}
203}
204