Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / file_mdm / file_mdm_exif / tests / src / Kernel / FileMetadataExifTest.php
1 <?php
2
3 namespace Drupal\Tests\file_mdm_exif\Kernel;
4
5 use Drupal\file_mdm\FileMetadataInterface;
6 use Drupal\Tests\file_mdm\Kernel\FileMetadataManagerTestBase;
7 use lsolesen\pel\PelEntryAscii;
8 use lsolesen\pel\PelEntryRational;
9 use lsolesen\pel\PelEntrySRational;
10
11 /**
12  * Tests that File Metadata EXIF plugin works properly.
13  *
14  * @group File Metadata
15  */
16 class FileMetadataExifTest extends FileMetadataManagerTestBase {
17
18   /**
19    * Modules to enable.
20    *
21    * @var array
22    */
23   public static $modules = [
24     'system',
25     'simpletest',
26     'file_mdm',
27     'file_mdm_exif',
28     'file_test',
29     'image_effects',
30   ];
31
32   /**
33    * {@inheritdoc}
34    */
35   public function setUp() {
36     parent::setUp();
37     $this->installConfig(['file_mdm_exif']);
38   }
39
40   /**
41    * Test EXIF plugin.
42    */
43   public function testExifPlugin() {
44     // Prepare a copy of test files.
45     file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-test.jpg', 'public://', FILE_EXISTS_REPLACE);
46     file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-test.png', 'public://', FILE_EXISTS_REPLACE);
47     file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg', 'public://', FILE_EXISTS_REPLACE);
48     file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg', 'temporary://', FILE_EXISTS_REPLACE);
49     // The image files that will be tested.
50     $image_files = [
51       [
52         // Pass a path instead of the URI.
53         'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg',
54         'count_keys' => 48,
55         'test_keys' => [
56           ['Orientation', 8],
57           ['orientation', 8],
58           ['OrIeNtAtIoN', 8],
59           ['ShutterSpeedValue', [106, 32]],
60           ['ApertureValue', [128, 32]],
61           [['exif', 'aperturevalue'], [128, 32]],
62           [[2, 'aperturevalue'], [128, 32]],
63           [['exif', 0x9202], [128, 32]],
64           [[2, 0x9202], [128, 32]],
65         ],
66       ],
67       [
68         // Pass a URI.
69         'uri' => 'public://test-exif.jpeg',
70         'count_keys' => 48,
71         'test_keys' => [
72           ['Orientation', 8],
73           ['ShutterSpeedValue', [106, 32]],
74         ],
75       ],
76       [
77         // Remote storage file. Let the file be copied to a local temp copy.
78         'uri' => 'dummy-remote://test-exif.jpeg',
79         'copy_to_temp' => TRUE,
80         'count_keys' => 48,
81         'test_keys' => [
82           ['Orientation', 8],
83           ['ShutterSpeedValue', [106, 32]],
84         ],
85       ],
86       [
87         // JPEG Image with GPS data.
88         'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/1024-2006_1011_093752.jpg',
89         'count_keys' => 59,
90         'test_keys' => [
91           ['Orientation', 1],
92           ['FocalLength', [8513, 256]],
93           ['GPSLatitudeRef', 'S'],
94           ['GPSLatitude', [[33, 1], [51, 1], [2191, 100]]],
95           ['GPSLongitudeRef', 'E'],
96           ['GPSLongitude', [[151, 1], [13, 1], [1173, 100]]],
97         ],
98       ],
99       [
100         // JPEG Image with no EXIF data.
101         'uri' => 'public://image-test.jpg',
102         'count_keys' => 0,
103         'test_keys' => [],
104       ],
105       [
106         // TIFF image.
107         'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/sample-1.tiff',
108         'count_keys' => 11,
109         'test_keys' => [
110           ['Orientation', 1],
111           ['BitsPerSample', [8, 8, 8, 8]],
112         ],
113       ],
114       [
115         // PNG should not have any data.
116         'uri' => 'public://image-test.png',
117         'count_keys' => 0,
118         'test_keys' => [],
119       ],
120     ];
121
122     $fmdm = $this->container->get('file_metadata_manager');
123
124     // Walk through test files.
125     foreach ($image_files as $image_file) {
126       $file_metadata = $fmdm->uri($image_file['uri']);
127       if (!$file_metadata) {
128         $this->fail("File not found: {$image_file['uri']}");
129         continue;
130       }
131       if (isset($image_file['copy_to_temp'])) {
132         $file_metadata->copyUriToTemp();
133       }
134       $this->assertEqual($image_file['count_keys'], $this->countMetadataKeys($file_metadata, 'exif'));
135       foreach ($image_file['test_keys'] as $test) {
136         $entry = $file_metadata->getMetadata('exif', $test[0]);
137         $this->assertEqual($test[1], $entry ? $entry['value'] : NULL);
138       }
139     }
140
141     // Test loading metadata from an in-memory object.
142     $file_metadata_from = $fmdm->uri($image_files[0]['uri']);
143     $metadata = $file_metadata_from->getMetadata('exif');
144     $new_file_metadata = $fmdm->uri('public://test-output.jpeg');
145     $new_file_metadata->loadMetadata('exif', $metadata);
146     $this->assertEqual($image_files[0]['count_keys'], $this->countMetadataKeys($new_file_metadata, 'exif'));
147     foreach ($image_files[0]['test_keys'] as $test) {
148       $entry = $file_metadata->getMetadata('exif', $test[0]);
149       $this->assertEqual($test[1], $new_file_metadata->getMetadata('exif', $test[0])['value']);
150     }
151
152     // Test removing metadata.
153     $fmdm->release($image_files[0]['uri']);
154     $this->assertFalse($fmdm->has($image_files[0]['uri']));
155     $file_metadata = $fmdm->uri($image_files[0]['uri']);
156     $this->assertEqual($image_files[0]['count_keys'], $this->countMetadataKeys($file_metadata, 'exif'));
157     $this->assertTrue($file_metadata->removeMetadata('exif', 'shutterspeedValue'));
158     $this->assertTrue($file_metadata->removeMetadata('exif', 'apertureValue'));
159     $this->assertFalse($file_metadata->removeMetadata('exif', 'bar'));
160     $this->assertEqual($image_files[0]['count_keys'] - 2, $this->countMetadataKeys($file_metadata, 'exif'));
161     $this->assertNull($file_metadata->getMetadata('exif', 'shutterspeedValue'));
162     $this->assertNull($file_metadata->getMetadata('exif', 'apertureValue'));
163     $this->assertNotNull($file_metadata->getMetadata('exif', 'orientation'));
164   }
165
166   /**
167    * Test writing metadata to JPEG file.
168    */
169   public function testJpegExifSaveToFile() {
170     $fmdm = $this->container->get('file_metadata_manager');
171
172     // Copy test file to public://.
173     file_unmanaged_copy(drupal_get_path('module', 'image_effects') . '/tests/images/portrait-painting.jpg', 'public://', FILE_EXISTS_REPLACE);
174     $file_uri = 'public://portrait-painting.jpg';
175     $file_metadata = $fmdm->uri($file_uri);
176
177     // Check values via exif_read_data before operations.
178     $data = @exif_read_data($file_uri);
179     $this->assertEqual(8, $data['Orientation']);
180     $this->assertFalse(isset($data['Artist']));
181     $this->assertEqual('Canon', $data['Make']);
182     $this->assertEqual(800, $data['ISOSpeedRatings']);
183
184     // Change the Orientation tag from IFD0.
185     $this->assertEqual(8, $file_metadata->getMetadata('exif', 'orientation')['value']);
186     $this->assertTrue($file_metadata->setMetadata('exif', 'orientation', 4));
187     $this->assertEqual(4, $file_metadata->getMetadata('exif', 'orientation')['value']);
188     // Add the Artist tag to IFD0.
189     $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
190     $this->assertNull($file_metadata->getMetadata('exif', 'artist'));
191     $artist_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('artist');
192     $artist = new PelEntryAscii($artist_tag['tag'], 'shot by foo!');
193     $file_metadata->setMetadata('exif', 'artist', $artist);
194     $this->assertEqual('shot by foo!', $file_metadata->getMetadata('exif', 'artist')['value']);
195     $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
196     // Setting an unknown tag leads to failure.
197     $this->assertFalse($file_metadata->setMetadata('exif', 'bar', 'qux'));
198     // Remove the Make tag from IFD0.
199     $this->assertEqual('Canon', $file_metadata->getMetadata('exif', 'make')['value']);
200     $this->assertTrue($file_metadata->removeMetadata('exif', 'make'));
201     $this->assertNull($file_metadata->getMetadata('exif', 'make'));
202     $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
203
204     // Add the ImageDescription tag to IFD1.
205     $this->assertNull($file_metadata->getMetadata('exif', [1, 'imagedescription']));
206     $desc_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag([1, 'imagedescription']);
207     $desc = new PelEntryAscii($desc_tag['tag'], 'awesome!');
208     $file_metadata->setMetadata('exif', [1, 'imagedescription'], $desc);
209     $this->assertEqual('awesome!', $file_metadata->getMetadata('exif', [1, 'imagedescription'])['value']);
210     $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
211     // Remove the Compression tag from IFD1.
212     $this->assertEqual(6, $file_metadata->getMetadata('exif', [1, 'compression'])['value']);
213     $this->assertTrue($file_metadata->removeMetadata('exif', [1, 'compression']));
214     $this->assertNull($file_metadata->getMetadata('exif', [1, 'compression']));
215     $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
216
217     // Add the BrightnessValue tag to EXIF.
218     $this->assertNull($file_metadata->getMetadata('exif', ['exif', 'brightnessvalue']));
219     $brightness_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag(['exif', 'brightnessvalue']);
220     $brightness = new PelEntrySRational($brightness_tag['tag'], [12, 4]);
221     $file_metadata->setMetadata('exif', ['exif', 'brightnessvalue'], $brightness);
222     $this->assertEqual('12/4', $file_metadata->getMetadata('exif', ['exif', 'brightnessvalue'])['text']);
223     $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
224     // Remove the ISOSpeedRatings tag from EXIF.
225     $this->assertEqual(800, $file_metadata->getMetadata('exif', ['exif', 'isospeedratings'])['value']);
226     $this->assertTrue($file_metadata->removeMetadata('exif', ['exif', 'isospeedratings']));
227     $this->assertNull($file_metadata->getMetadata('exif', ['exif', 'isospeedratings']));
228     $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
229
230     // Add the RelatedImageFileFormat tag to INTEROP.
231     $this->assertNull($file_metadata->getMetadata('exif', ['interop', 'RelatedImageFileFormat']));
232     $ff_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag(['interop', 'RelatedImageFileFormat']);
233     $ff = new PelEntryAscii($ff_tag['tag'], 'qux');
234     $file_metadata->setMetadata('exif', ['interop', 'RelatedImageFileFormat'], $ff);
235     $this->assertEqual('qux', $file_metadata->getMetadata('exif', ['interop', 'RelatedImageFileFormat'])['text']);
236     $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
237     // Remove the InteroperabilityIndex tag from INTEROP.
238     $this->assertEqual('R98', $file_metadata->getMetadata('exif', ['interop', 'InteroperabilityIndex'])['value']);
239     $this->assertTrue($file_metadata->removeMetadata('exif', ['interop', 'InteroperabilityIndex']));
240     $this->assertNull($file_metadata->getMetadata('exif', ['interop', 'InteroperabilityIndex']));
241     $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
242
243     // Add Longitude/Latitude tags to GPS.
244     $this->assertNull($file_metadata->getMetadata('exif', 'GPSLatitudeRef'));
245     $this->assertNull($file_metadata->getMetadata('exif', 'GPSLatitude'));
246     $this->assertNull($file_metadata->getMetadata('exif', 'GPSLongitudeRef'));
247     $this->assertNull($file_metadata->getMetadata('exif', 'GPSLongitude'));
248     $atr_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLatitudeRef');
249     $at_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLatitude');
250     $otr_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLongitudeRef');
251     $ot_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLongitude');
252     $atr = new PelEntryAscii($atr_tag['tag'], 'N');
253     $at = new PelEntryRational($at_tag['tag'], [46, 1], [37, 1], [59448, 10000]);
254     $otr = new PelEntryAscii($otr_tag['tag'], 'E');
255     $ot = new PelEntryRational($ot_tag['tag'], [12, 1], [17, 1], [488112, 10000]);
256     $file_metadata->setMetadata('exif', 'GPSLatitudeRef', $atr);
257     $file_metadata->setMetadata('exif', 'GPSLatitude', $at);
258     $file_metadata->setMetadata('exif', 'GPSLongitudeRef', $otr);
259     $file_metadata->setMetadata('exif', 'GPSLongitude', $ot);
260     $this->assertEqual('N', $file_metadata->getMetadata('exif', 'GPSLatitudeRef')['text']);
261     $this->assertNotNull($file_metadata->getMetadata('exif', 'GPSLatitude')['text']);
262     $this->assertEqual('E', $file_metadata->getMetadata('exif', 'GPSLongitudeRef')['text']);
263     $this->assertNotNull($file_metadata->getMetadata('exif', 'GPSLongitude')['text']);
264     $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
265
266     // Save metadata to file.
267     $this->assertTrue($file_metadata->saveMetadataToFile('exif'));
268
269     // Check results via exif_read_data.
270     $data = @exif_read_data($file_uri);
271     $this->assertEqual(4, $data['Orientation']);
272     $this->assertEqual('shot by foo!', $data['Artist']);
273     $this->assertFalse(isset($data['Make']));
274     $this->assertEqual('12/4', $data['BrightnessValue']);
275     $this->assertFalse(isset($data['ISOSpeedRatings']));
276     $this->assertEqual('qux', $data['RelatedFileFormat']);
277     $this->assertFalse(isset($data['InterOperabilityIndex']));
278     $this->assertEqual('N', $data['GPSLatitudeRef']);
279     $this->assertEqual(['46/1', '37/1', '59448/10000'], $data['GPSLatitude']);
280     $this->assertEqual('E', $data['GPSLongitudeRef']);
281     $this->assertEqual(['12/1', '17/1', '488112/10000'], $data['GPSLongitude']);
282
283     // Test writing metadata to a file that has no EXIF info.
284     file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-2.jpg', 'public://', FILE_EXISTS_REPLACE);
285     $test_2 = $fmdm->uri('public://image-2.jpg');
286     $this->assertEqual(0, $this->countMetadataKeys($test_2, 'exif'));
287     // Load EXIF metadata from previous file processed.
288     $test_2->loadMetadata('exif', $file_metadata->getMetadata('exif'));
289     // Save metadata to file.
290     $this->assertTrue($test_2->saveMetadataToFile('exif'));
291     $this->assertEqual(52, $this->countMetadataKeys($test_2, 'exif'));
292     // Check results via exif_read_data.
293     $data = @exif_read_data('public://image-2.jpg');
294     $this->assertEqual(4, $data['Orientation']);
295     $this->assertEqual('shot by foo!', $data['Artist']);
296     $this->assertEqual('12/4', $data['BrightnessValue']);
297     $this->assertEqual('qux', $data['RelatedFileFormat']);
298     $this->assertEqual('N', $data['GPSLatitudeRef']);
299     $this->assertEqual(['46/1', '37/1', '59448/10000'], $data['GPSLatitude']);
300     $this->assertEqual('E', $data['GPSLongitudeRef']);
301     $this->assertEqual(['12/1', '17/1', '488112/10000'], $data['GPSLongitude']);
302
303     // Check that after save, file metadata is retrieved from file first time,
304     // then from cache in further requests.
305     $file_metadata = NULL;
306     $this->assertTrue($fmdm->release($file_uri));
307     $file_metadata = $fmdm->uri($file_uri);
308     $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
309     $this->assertIdentical(FileMetadataInterface::LOADED_FROM_FILE, $file_metadata->isMetadataLoaded('exif'));
310     $file_metadata = NULL;
311     $this->assertTrue($fmdm->release($file_uri));
312     $file_metadata = $fmdm->uri($file_uri);
313     $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
314     $this->assertIdentical(FileMetadataInterface::LOADED_FROM_CACHE, $file_metadata->isMetadataLoaded('exif'));
315   }
316
317   /**
318    * Test writing metadata to TIFF file.
319    */
320   public function testTiffExifSaveToFile() {
321     $fmdm = $this->container->get('file_metadata_manager');
322
323     // Copy test file to public://.
324     file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/sample-1.tiff', 'public://', FILE_EXISTS_REPLACE);
325     $file_uri = 'public://sample-1.tiff';
326     $file_metadata = $fmdm->uri($file_uri);
327
328     // Check values via exif_read_data before operations.
329     $data = @exif_read_data($file_uri);
330     $this->assertEqual(1, $data['Orientation']);
331     $this->assertEqual(2, $data['PhotometricInterpretation']);
332
333     // Change tags from IFD0.
334     $this->assertEqual(1, $file_metadata->getMetadata('exif', 'orientation')['value']);
335     $this->assertTrue($file_metadata->setMetadata('exif', 'orientation', 4));
336     $this->assertEqual(4, $file_metadata->getMetadata('exif', 'orientation')['value']);
337     $this->assertEqual(2, $file_metadata->getMetadata('exif', 'PhotometricInterpretation')['value']);
338     $this->assertTrue($file_metadata->setMetadata('exif', 'PhotometricInterpretation', 4));
339     $this->assertEqual(4, $file_metadata->getMetadata('exif', 'PhotometricInterpretation')['value']);
340
341     // Save metadata to file.
342     $this->assertTrue($file_metadata->saveMetadataToFile('exif'));
343
344     // Check results via exif_read_data.
345     $data = @exif_read_data($file_uri);
346     $this->assertEqual(4, $data['Orientation']);
347     $this->assertEqual(4, $data['PhotometricInterpretation']);
348   }
349
350 }