Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / file_mdm / file_mdm_exif / tests / src / Kernel / FileMetadataExifTest.php
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/tests/src/Kernel/FileMetadataExifTest.php b/web/modules/contrib/file_mdm/file_mdm_exif/tests/src/Kernel/FileMetadataExifTest.php
new file mode 100644 (file)
index 0000000..ce9a818
--- /dev/null
@@ -0,0 +1,350 @@
+<?php
+
+namespace Drupal\Tests\file_mdm_exif\Kernel;
+
+use Drupal\file_mdm\FileMetadataInterface;
+use Drupal\Tests\file_mdm\Kernel\FileMetadataManagerTestBase;
+use lsolesen\pel\PelEntryAscii;
+use lsolesen\pel\PelEntryRational;
+use lsolesen\pel\PelEntrySRational;
+
+/**
+ * Tests that File Metadata EXIF plugin works properly.
+ *
+ * @group File Metadata
+ */
+class FileMetadataExifTest extends FileMetadataManagerTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'system',
+    'simpletest',
+    'file_mdm',
+    'file_mdm_exif',
+    'file_test',
+    'image_effects',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->installConfig(['file_mdm_exif']);
+  }
+
+  /**
+   * Test EXIF plugin.
+   */
+  public function testExifPlugin() {
+    // Prepare a copy of test files.
+    file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-test.jpg', 'public://', FILE_EXISTS_REPLACE);
+    file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-test.png', 'public://', FILE_EXISTS_REPLACE);
+    file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg', 'public://', FILE_EXISTS_REPLACE);
+    file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg', 'temporary://', FILE_EXISTS_REPLACE);
+    // The image files that will be tested.
+    $image_files = [
+      [
+        // Pass a path instead of the URI.
+        'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg',
+        'count_keys' => 48,
+        'test_keys' => [
+          ['Orientation', 8],
+          ['orientation', 8],
+          ['OrIeNtAtIoN', 8],
+          ['ShutterSpeedValue', [106, 32]],
+          ['ApertureValue', [128, 32]],
+          [['exif', 'aperturevalue'], [128, 32]],
+          [[2, 'aperturevalue'], [128, 32]],
+          [['exif', 0x9202], [128, 32]],
+          [[2, 0x9202], [128, 32]],
+        ],
+      ],
+      [
+        // Pass a URI.
+        'uri' => 'public://test-exif.jpeg',
+        'count_keys' => 48,
+        'test_keys' => [
+          ['Orientation', 8],
+          ['ShutterSpeedValue', [106, 32]],
+        ],
+      ],
+      [
+        // Remote storage file. Let the file be copied to a local temp copy.
+        'uri' => 'dummy-remote://test-exif.jpeg',
+        'copy_to_temp' => TRUE,
+        'count_keys' => 48,
+        'test_keys' => [
+          ['Orientation', 8],
+          ['ShutterSpeedValue', [106, 32]],
+        ],
+      ],
+      [
+        // JPEG Image with GPS data.
+        'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/1024-2006_1011_093752.jpg',
+        'count_keys' => 59,
+        'test_keys' => [
+          ['Orientation', 1],
+          ['FocalLength', [8513, 256]],
+          ['GPSLatitudeRef', 'S'],
+          ['GPSLatitude', [[33, 1], [51, 1], [2191, 100]]],
+          ['GPSLongitudeRef', 'E'],
+          ['GPSLongitude', [[151, 1], [13, 1], [1173, 100]]],
+        ],
+      ],
+      [
+        // JPEG Image with no EXIF data.
+        'uri' => 'public://image-test.jpg',
+        'count_keys' => 0,
+        'test_keys' => [],
+      ],
+      [
+        // TIFF image.
+        'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/sample-1.tiff',
+        'count_keys' => 11,
+        'test_keys' => [
+          ['Orientation', 1],
+          ['BitsPerSample', [8, 8, 8, 8]],
+        ],
+      ],
+      [
+        // PNG should not have any data.
+        'uri' => 'public://image-test.png',
+        'count_keys' => 0,
+        'test_keys' => [],
+      ],
+    ];
+
+    $fmdm = $this->container->get('file_metadata_manager');
+
+    // Walk through test files.
+    foreach ($image_files as $image_file) {
+      $file_metadata = $fmdm->uri($image_file['uri']);
+      if (!$file_metadata) {
+        $this->fail("File not found: {$image_file['uri']}");
+        continue;
+      }
+      if (isset($image_file['copy_to_temp'])) {
+        $file_metadata->copyUriToTemp();
+      }
+      $this->assertEqual($image_file['count_keys'], $this->countMetadataKeys($file_metadata, 'exif'));
+      foreach ($image_file['test_keys'] as $test) {
+        $entry = $file_metadata->getMetadata('exif', $test[0]);
+        $this->assertEqual($test[1], $entry ? $entry['value'] : NULL);
+      }
+    }
+
+    // Test loading metadata from an in-memory object.
+    $file_metadata_from = $fmdm->uri($image_files[0]['uri']);
+    $metadata = $file_metadata_from->getMetadata('exif');
+    $new_file_metadata = $fmdm->uri('public://test-output.jpeg');
+    $new_file_metadata->loadMetadata('exif', $metadata);
+    $this->assertEqual($image_files[0]['count_keys'], $this->countMetadataKeys($new_file_metadata, 'exif'));
+    foreach ($image_files[0]['test_keys'] as $test) {
+      $entry = $file_metadata->getMetadata('exif', $test[0]);
+      $this->assertEqual($test[1], $new_file_metadata->getMetadata('exif', $test[0])['value']);
+    }
+
+    // Test removing metadata.
+    $fmdm->release($image_files[0]['uri']);
+    $this->assertFalse($fmdm->has($image_files[0]['uri']));
+    $file_metadata = $fmdm->uri($image_files[0]['uri']);
+    $this->assertEqual($image_files[0]['count_keys'], $this->countMetadataKeys($file_metadata, 'exif'));
+    $this->assertTrue($file_metadata->removeMetadata('exif', 'shutterspeedValue'));
+    $this->assertTrue($file_metadata->removeMetadata('exif', 'apertureValue'));
+    $this->assertFalse($file_metadata->removeMetadata('exif', 'bar'));
+    $this->assertEqual($image_files[0]['count_keys'] - 2, $this->countMetadataKeys($file_metadata, 'exif'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'shutterspeedValue'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'apertureValue'));
+    $this->assertNotNull($file_metadata->getMetadata('exif', 'orientation'));
+  }
+
+  /**
+   * Test writing metadata to JPEG file.
+   */
+  public function testJpegExifSaveToFile() {
+    $fmdm = $this->container->get('file_metadata_manager');
+
+    // Copy test file to public://.
+    file_unmanaged_copy(drupal_get_path('module', 'image_effects') . '/tests/images/portrait-painting.jpg', 'public://', FILE_EXISTS_REPLACE);
+    $file_uri = 'public://portrait-painting.jpg';
+    $file_metadata = $fmdm->uri($file_uri);
+
+    // Check values via exif_read_data before operations.
+    $data = @exif_read_data($file_uri);
+    $this->assertEqual(8, $data['Orientation']);
+    $this->assertFalse(isset($data['Artist']));
+    $this->assertEqual('Canon', $data['Make']);
+    $this->assertEqual(800, $data['ISOSpeedRatings']);
+
+    // Change the Orientation tag from IFD0.
+    $this->assertEqual(8, $file_metadata->getMetadata('exif', 'orientation')['value']);
+    $this->assertTrue($file_metadata->setMetadata('exif', 'orientation', 4));
+    $this->assertEqual(4, $file_metadata->getMetadata('exif', 'orientation')['value']);
+    // Add the Artist tag to IFD0.
+    $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'artist'));
+    $artist_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('artist');
+    $artist = new PelEntryAscii($artist_tag['tag'], 'shot by foo!');
+    $file_metadata->setMetadata('exif', 'artist', $artist);
+    $this->assertEqual('shot by foo!', $file_metadata->getMetadata('exif', 'artist')['value']);
+    $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+    // Setting an unknown tag leads to failure.
+    $this->assertFalse($file_metadata->setMetadata('exif', 'bar', 'qux'));
+    // Remove the Make tag from IFD0.
+    $this->assertEqual('Canon', $file_metadata->getMetadata('exif', 'make')['value']);
+    $this->assertTrue($file_metadata->removeMetadata('exif', 'make'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'make'));
+    $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+    // Add the ImageDescription tag to IFD1.
+    $this->assertNull($file_metadata->getMetadata('exif', [1, 'imagedescription']));
+    $desc_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag([1, 'imagedescription']);
+    $desc = new PelEntryAscii($desc_tag['tag'], 'awesome!');
+    $file_metadata->setMetadata('exif', [1, 'imagedescription'], $desc);
+    $this->assertEqual('awesome!', $file_metadata->getMetadata('exif', [1, 'imagedescription'])['value']);
+    $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+    // Remove the Compression tag from IFD1.
+    $this->assertEqual(6, $file_metadata->getMetadata('exif', [1, 'compression'])['value']);
+    $this->assertTrue($file_metadata->removeMetadata('exif', [1, 'compression']));
+    $this->assertNull($file_metadata->getMetadata('exif', [1, 'compression']));
+    $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+    // Add the BrightnessValue tag to EXIF.
+    $this->assertNull($file_metadata->getMetadata('exif', ['exif', 'brightnessvalue']));
+    $brightness_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag(['exif', 'brightnessvalue']);
+    $brightness = new PelEntrySRational($brightness_tag['tag'], [12, 4]);
+    $file_metadata->setMetadata('exif', ['exif', 'brightnessvalue'], $brightness);
+    $this->assertEqual('12/4', $file_metadata->getMetadata('exif', ['exif', 'brightnessvalue'])['text']);
+    $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+    // Remove the ISOSpeedRatings tag from EXIF.
+    $this->assertEqual(800, $file_metadata->getMetadata('exif', ['exif', 'isospeedratings'])['value']);
+    $this->assertTrue($file_metadata->removeMetadata('exif', ['exif', 'isospeedratings']));
+    $this->assertNull($file_metadata->getMetadata('exif', ['exif', 'isospeedratings']));
+    $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+    // Add the RelatedImageFileFormat tag to INTEROP.
+    $this->assertNull($file_metadata->getMetadata('exif', ['interop', 'RelatedImageFileFormat']));
+    $ff_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag(['interop', 'RelatedImageFileFormat']);
+    $ff = new PelEntryAscii($ff_tag['tag'], 'qux');
+    $file_metadata->setMetadata('exif', ['interop', 'RelatedImageFileFormat'], $ff);
+    $this->assertEqual('qux', $file_metadata->getMetadata('exif', ['interop', 'RelatedImageFileFormat'])['text']);
+    $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+    // Remove the InteroperabilityIndex tag from INTEROP.
+    $this->assertEqual('R98', $file_metadata->getMetadata('exif', ['interop', 'InteroperabilityIndex'])['value']);
+    $this->assertTrue($file_metadata->removeMetadata('exif', ['interop', 'InteroperabilityIndex']));
+    $this->assertNull($file_metadata->getMetadata('exif', ['interop', 'InteroperabilityIndex']));
+    $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+    // Add Longitude/Latitude tags to GPS.
+    $this->assertNull($file_metadata->getMetadata('exif', 'GPSLatitudeRef'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'GPSLatitude'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'GPSLongitudeRef'));
+    $this->assertNull($file_metadata->getMetadata('exif', 'GPSLongitude'));
+    $atr_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLatitudeRef');
+    $at_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLatitude');
+    $otr_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLongitudeRef');
+    $ot_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLongitude');
+    $atr = new PelEntryAscii($atr_tag['tag'], 'N');
+    $at = new PelEntryRational($at_tag['tag'], [46, 1], [37, 1], [59448, 10000]);
+    $otr = new PelEntryAscii($otr_tag['tag'], 'E');
+    $ot = new PelEntryRational($ot_tag['tag'], [12, 1], [17, 1], [488112, 10000]);
+    $file_metadata->setMetadata('exif', 'GPSLatitudeRef', $atr);
+    $file_metadata->setMetadata('exif', 'GPSLatitude', $at);
+    $file_metadata->setMetadata('exif', 'GPSLongitudeRef', $otr);
+    $file_metadata->setMetadata('exif', 'GPSLongitude', $ot);
+    $this->assertEqual('N', $file_metadata->getMetadata('exif', 'GPSLatitudeRef')['text']);
+    $this->assertNotNull($file_metadata->getMetadata('exif', 'GPSLatitude')['text']);
+    $this->assertEqual('E', $file_metadata->getMetadata('exif', 'GPSLongitudeRef')['text']);
+    $this->assertNotNull($file_metadata->getMetadata('exif', 'GPSLongitude')['text']);
+    $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
+
+    // Save metadata to file.
+    $this->assertTrue($file_metadata->saveMetadataToFile('exif'));
+
+    // Check results via exif_read_data.
+    $data = @exif_read_data($file_uri);
+    $this->assertEqual(4, $data['Orientation']);
+    $this->assertEqual('shot by foo!', $data['Artist']);
+    $this->assertFalse(isset($data['Make']));
+    $this->assertEqual('12/4', $data['BrightnessValue']);
+    $this->assertFalse(isset($data['ISOSpeedRatings']));
+    $this->assertEqual('qux', $data['RelatedFileFormat']);
+    $this->assertFalse(isset($data['InterOperabilityIndex']));
+    $this->assertEqual('N', $data['GPSLatitudeRef']);
+    $this->assertEqual(['46/1', '37/1', '59448/10000'], $data['GPSLatitude']);
+    $this->assertEqual('E', $data['GPSLongitudeRef']);
+    $this->assertEqual(['12/1', '17/1', '488112/10000'], $data['GPSLongitude']);
+
+    // Test writing metadata to a file that has no EXIF info.
+    file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-2.jpg', 'public://', FILE_EXISTS_REPLACE);
+    $test_2 = $fmdm->uri('public://image-2.jpg');
+    $this->assertEqual(0, $this->countMetadataKeys($test_2, 'exif'));
+    // Load EXIF metadata from previous file processed.
+    $test_2->loadMetadata('exif', $file_metadata->getMetadata('exif'));
+    // Save metadata to file.
+    $this->assertTrue($test_2->saveMetadataToFile('exif'));
+    $this->assertEqual(52, $this->countMetadataKeys($test_2, 'exif'));
+    // Check results via exif_read_data.
+    $data = @exif_read_data('public://image-2.jpg');
+    $this->assertEqual(4, $data['Orientation']);
+    $this->assertEqual('shot by foo!', $data['Artist']);
+    $this->assertEqual('12/4', $data['BrightnessValue']);
+    $this->assertEqual('qux', $data['RelatedFileFormat']);
+    $this->assertEqual('N', $data['GPSLatitudeRef']);
+    $this->assertEqual(['46/1', '37/1', '59448/10000'], $data['GPSLatitude']);
+    $this->assertEqual('E', $data['GPSLongitudeRef']);
+    $this->assertEqual(['12/1', '17/1', '488112/10000'], $data['GPSLongitude']);
+
+    // Check that after save, file metadata is retrieved from file first time,
+    // then from cache in further requests.
+    $file_metadata = NULL;
+    $this->assertTrue($fmdm->release($file_uri));
+    $file_metadata = $fmdm->uri($file_uri);
+    $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
+    $this->assertIdentical(FileMetadataInterface::LOADED_FROM_FILE, $file_metadata->isMetadataLoaded('exif'));
+    $file_metadata = NULL;
+    $this->assertTrue($fmdm->release($file_uri));
+    $file_metadata = $fmdm->uri($file_uri);
+    $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
+    $this->assertIdentical(FileMetadataInterface::LOADED_FROM_CACHE, $file_metadata->isMetadataLoaded('exif'));
+  }
+
+  /**
+   * Test writing metadata to TIFF file.
+   */
+  public function testTiffExifSaveToFile() {
+    $fmdm = $this->container->get('file_metadata_manager');
+
+    // Copy test file to public://.
+    file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/sample-1.tiff', 'public://', FILE_EXISTS_REPLACE);
+    $file_uri = 'public://sample-1.tiff';
+    $file_metadata = $fmdm->uri($file_uri);
+
+    // Check values via exif_read_data before operations.
+    $data = @exif_read_data($file_uri);
+    $this->assertEqual(1, $data['Orientation']);
+    $this->assertEqual(2, $data['PhotometricInterpretation']);
+
+    // Change tags from IFD0.
+    $this->assertEqual(1, $file_metadata->getMetadata('exif', 'orientation')['value']);
+    $this->assertTrue($file_metadata->setMetadata('exif', 'orientation', 4));
+    $this->assertEqual(4, $file_metadata->getMetadata('exif', 'orientation')['value']);
+    $this->assertEqual(2, $file_metadata->getMetadata('exif', 'PhotometricInterpretation')['value']);
+    $this->assertTrue($file_metadata->setMetadata('exif', 'PhotometricInterpretation', 4));
+    $this->assertEqual(4, $file_metadata->getMetadata('exif', 'PhotometricInterpretation')['value']);
+
+    // Save metadata to file.
+    $this->assertTrue($file_metadata->saveMetadataToFile('exif'));
+
+    // Check results via exif_read_data.
+    $data = @exif_read_data($file_uri);
+    $this->assertEqual(4, $data['Orientation']);
+    $this->assertEqual(4, $data['PhotometricInterpretation']);
+  }
+
+}