aboutsummaryrefslogtreecommitdiffstats
path: root/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php
blob: 8240e71c4ba56a4de00da85e1e7976dbbf65faf6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php

use MediaWiki\MainConfigNames;

/**
 * @group Media
 */
class BitmapMetadataHandlerTest extends MediaWikiIntegrationTestCase {
	private const FILE_PATH = __DIR__ . '/../../data/media/';

	protected function setUp(): void {
		parent::setUp();

		$this->overrideConfigValue( MainConfigNames::ShowEXIF, false );
	}

	/**
	 * Test if having conflicting metadata values from different
	 * types of metadata, that the right one takes precedence.
	 *
	 * Basically the file has IPTC and XMP metadata, the
	 * IPTC should override the XMP, except for the multilingual
	 * translation (to en) where XMP should win.
	 * @covers \BitmapMetadataHandler::Jpeg
	 * @requires extension exif
	 */
	public function testMultilingualCascade() {
		$this->overrideConfigValue( MainConfigNames::ShowEXIF, true );

		$meta = BitmapMetadataHandler::Jpeg( self::FILE_PATH .
			'/Xmp-exif-multilingual_test.jpg' );

		$expected = [
			'x-default' => 'right(iptc)',
			'en' => 'right translation',
			'_type' => 'lang'
		];

		$this->assertArrayHasKey( 'ImageDescription', $meta,
			'Did not extract any ImageDescription info?!' );

		$this->assertEquals( $expected, $meta['ImageDescription'] );
	}

	/**
	 * Test for jpeg comments are being handled by
	 * BitmapMetadataHandler correctly.
	 *
	 * There's more extensive tests of comment extraction in
	 * JpegMetadataExtractorTests.php
	 * @covers \BitmapMetadataHandler::Jpeg
	 */
	public function testJpegComment() {
		$meta = BitmapMetadataHandler::Jpeg( self::FILE_PATH .
			'jpeg-comment-utf.jpg' );

		$this->assertEquals( 'UTF-8 JPEG Comment — ¼',
			$meta['JPEGFileComment'][0] );
	}

	/**
	 * Make sure a bad iptc block doesn't stop the other metadata
	 * from being extracted.
	 * @covers \BitmapMetadataHandler::Jpeg
	 */
	public function testBadIPTC() {
		$meta = BitmapMetadataHandler::Jpeg( self::FILE_PATH .
			'iptc-invalid-psir.jpg' );
		$this->assertEquals( 'Created with GIMP', $meta['JPEGFileComment'][0] );
	}

	/**
	 * @covers \BitmapMetadataHandler::Jpeg
	 */
	public function testIPTCDates() {
		$meta = BitmapMetadataHandler::Jpeg( self::FILE_PATH .
			'iptc-timetest.jpg' );

		// raw date is 2020:07:13 14:04:05+11:32
		$this->assertEquals( '2020:07:14 01:36:05', $meta['DateTimeDigitized'] );
		// raw date is 1997:03:02 03:01:02-03:00
		$this->assertEquals( '1997:03:02 00:01:02', $meta['DateTimeOriginal'] );

		$meta = BitmapMetadataHandler::Jpeg( self::FILE_PATH .
			'iptc-timetest-invalid.jpg' );

		// raw date is 1845:03:02 03:01:02-03:00
		$this->assertEquals( '1845:03:02 00:01:02', $meta['DateTimeOriginal'] );
		// raw date is 1942:07:13 25:05:02+00:00
		$this->assertSame( '1942:07:14 01:05:02', $meta['DateTimeDigitized'] );
	}

	/**
	 * XMP data should take priority over iptc data
	 * when hash has been updated, but not when
	 * the hash is wrong.
	 * @covers \BitmapMetadataHandler::addMetadata
	 * @covers \BitmapMetadataHandler::getMetadataArray
	 */
	public function testMerging() {
		$merger = new BitmapMetadataHandler();
		$merger->addMetadata( [ 'foo' => 'xmp' ], 'xmp-general' );
		$merger->addMetadata( [ 'bar' => 'xmp' ], 'xmp-general' );
		$merger->addMetadata( [ 'baz' => 'xmp' ], 'xmp-general' );
		$merger->addMetadata( [ 'fred' => 'xmp' ], 'xmp-general' );
		$merger->addMetadata( [ 'foo' => 'iptc (hash)' ], 'iptc-good-hash' );
		$merger->addMetadata( [ 'bar' => 'iptc (bad hash)' ], 'iptc-bad-hash' );
		$merger->addMetadata( [ 'baz' => 'iptc (bad hash)' ], 'iptc-bad-hash' );
		$merger->addMetadata( [ 'fred' => 'iptc (no hash)' ], 'iptc-no-hash' );
		$merger->addMetadata( [ 'baz' => 'exif' ], 'exif' );

		$actual = $merger->getMetadataArray();
		$expected = [
			'foo' => 'xmp',
			'bar' => 'iptc (bad hash)',
			'baz' => 'exif',
			'fred' => 'xmp',
		];
		$this->assertEquals( $expected, $actual );
	}

	/**
	 * @covers \BitmapMetadataHandler::png
	 */
	public function testPNGXMP() {
		$result = BitmapMetadataHandler::PNG( self::FILE_PATH . 'xmp.png' );
		$expected = [
			'width' => 50,
			'height' => 50,
			'frameCount' => 0,
			'loopCount' => 1,
			'duration' => 0,
			'bitDepth' => 1,
			'colorType' => 'index-coloured',
			'metadata' => [
				'SerialNumber' => '123456789',
				'_MW_PNG_VERSION' => 1,
			],
		];
		$this->assertEquals( $expected, $result );
	}

	/**
	 * @covers \BitmapMetadataHandler::png
	 */
	public function testPNGNative() {
		$result = BitmapMetadataHandler::PNG( self::FILE_PATH . 'Png-native-test.png' );
		$expected = 'http://example.com/url';
		$this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] );
	}

	/**
	 * @covers \BitmapMetadataHandler::getTiffByteOrder
	 */
	public function testTiffByteOrder() {
		$res = BitmapMetadataHandler::getTiffByteOrder( self::FILE_PATH . 'test.tiff' );
		$this->assertEquals( 'LE', $res );
	}
}