diff --git a/tests/src/Functional/ImageHandling.php b/tests/src/Functional/ImageHandling.php new file mode 100644 index 0000000..589f2dc --- /dev/null +++ b/tests/src/Functional/ImageHandling.php @@ -0,0 +1,547 @@ +loginUser1(); + + // Add a metatag field to the entity type test_entity. + $this->drupalGet('entity_test/structure/entity_test/fields/add-field'); + $this->assertResponse(200); + $edit = [ + 'label' => 'Metatag', + 'field_name' => 'metatag', + 'new_storage_type' => 'metatag', + ]; + $this->drupalPostForm(NULL, $edit, t('Save and continue')); + $this->drupalPostForm(NULL, [], t('Save field settings')); + $this->drupalPostForm(NULL, [], t('Save settings')); + $this->container->get('entity.manager')->clearCachedFieldDefinitions(); + + // Add an image field to the same entity. + $this->drupalGet('entity_test/structure/entity_test/fields/add-field'); + $this->assertResponse(200); + $edit = [ + 'label' => 'Image', + 'field_name' => 'image', + 'new_storage_type' => 'image', + ]; + $this->drupalPostForm(NULL, $edit, t('Save and continue')); + $this->drupalPostForm(NULL, [], t('Save field settings')); + $this->drupalPostForm(NULL, [], t('Save settings')); + $this->container->get('entity.manager')->clearCachedFieldDefinitions(); + } + + /** + * Confirm that an image can be added to a global configuration using the + * image's absolute URL. + */ + function testConfigAbsoluteURL() { + // Generate a test image. + $image_uri = $this->generateImage(); + $this->verbose($image_uri); + + // Work out the web-accessible URL for this image. + $image_url = file_create_url($image_uri); + + // Update the global config to add an image meta tag. + $config = metatag_config_load('global'); + $config->config['image_src']['value'] = $image_url; + metatag_config_save($config); + + // Dump out the current config, to aid with debugging. + $this->verbose('
' . print_r($config, TRUE) . '
'); + + // Load the front page. + $this->drupalGet(''); + $this->assertResponse(200); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual($xpath[0]['href'], $image_url, 'The image_src meta tag with an absolute URL is being output correctly.'); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that an image can be added to a global configuration using the + * image's relative URL. + */ + function testConfigDrupalRelativeURL() { + // Generate a test image. + $image_uri = $this->generateImage(); + $this->verbose($image_uri); + + // Work out the web-accessible URL for this image. + $image_url = file_create_url($image_uri); + + // Extract the relative URL version of the absolute URL. + $url_length = strlen($GLOBALS['base_url']); + + // Need to increase the length by 1 as the base_url does not include a + // trailing slash. + $relative_url = substr($image_url, $url_length + 1); + + // Update the global config to add an image meta tag. + $config = metatag_config_load('global'); + $config->config['image_src']['value'] = $relative_url; + metatag_config_save($config); + + // Dump out the current config, to aid with debugging. + $this->verbose('
' . print_r($config, TRUE) . '
'); + + // Load the front page. + $this->drupalGet(''); + $this->assertResponse(200); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual((string)$xpath[0]['href'], $image_url);//, 'The image_src meta tag with a URL relative to the Drupal root is being output as an absolute URL.'); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that an image can be added to a global configuration using the + * image's relative URL. + */ + function testConfigRelativeURL() { + // Generate a test image. + $image_uri = $this->generateImage(); + $this->verbose($image_uri); + + // Work out the web-accessible URL for this image. + $image_url = file_create_url($image_uri); + + // Extract the relative URL version of the absolute URL. + $url_length = drupal_strlen($GLOBALS['base_url']); + + // Need to increase the length by 1 as the base_url does not include a + // trailing slash. + $relative_url = drupal_substr($image_url, $url_length + 1); + + // Update the global config to add an image meta tag. + $config = metatag_config_load('global'); + $config->config['image_src']['value'] = $relative_url; + metatag_config_save($config); + + // Dump out the current config, to aid with debugging. + $this->verbose('
' . print_r($config, TRUE) . '
'); + + // Load the front page. + $this->drupalGet(''); + $this->assertResponse(200); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual((string)$xpath[0]['href'], $image_url);//, 'The image_src meta tag with an internal URI is being output as an absolute URL.'); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that an image can be added to a global configuration using the + * image's internal URI. + */ + function testConfigInternalURL() { + // Generate a test image. + $image_uri = $this->generateImage(); + $this->verbose($image_uri); + + // Work out the web-accessible URL for this image. + $image_url = file_create_url($image_uri); + + // Confirm the file could be loaded. + $this->drupalGet($image_url); + $this->assertResponse(200, 'The image could be loaded.'); + + // Update the global config to add an image meta tag. + $config = metatag_config_load('global'); + $config->config['image_src']['value'] = $image_uri; + metatag_config_save($config); + + // Dump out the current config, to aid with debugging. + $this->verbose('
' . print_r($config, TRUE) . '
'); + + // Load the front page. + $this->drupalGet(''); + $this->assertResponse(200); + + // Confirm that the image URL can be found in the raw HTML. + $this->assertRaw($image_url, 'Found the image URL in the raw HTML.'); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual($xpath[0]['href'], $image_url, 'The image_src meta tag with an internal URI is being output correctly.'); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that an image with a space in its URL will be handled properly. + */ + function testConfigImageWithSpaceInURL() { + // Generate a test image. + $image_uri = $this->generateImage(); + $this->verbose($image_uri); + + // Rename the file so it has a space in the filename. + $image_uri = file_unmanaged_move($image_uri, str_replace('_', ' ', $image_uri)); + $this->verbose($image_uri); + + // Work out the web-accessible URL for this image. + $image_url = file_create_url($image_uri); + + // Confirm the file could be loaded. + $this->drupalGet($image_url); + $this->assertResponse(200, 'The image could be loaded.'); + + // After processing the image's URL will have "%20" instead of spaces. + $image_url_friendly = str_replace(' ', '%20', $image_url); + + // Confirm the file's friendly URL could be loaded. + $this->drupalGet($image_url_friendly); + $this->assertResponse(200, 'The friendly image could be loaded.'); + + // Update the global config to add an image meta tag. + $config = metatag_config_load('global'); + $config->config['image_src']['value'] = $image_uri; + metatag_config_save($config); + + // Dump out the current config, to aid with debugging. + $this->verbose('
' . print_r($config, TRUE) . '
'); + + // Load the front page. + $this->drupalGet(''); + $this->assertResponse(200); + + // Confirm that the image's friendly URL can be found in the raw HTML. + $this->assertRaw($image_url_friendly, 'Found the friendly image URL in the raw HTML.'); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual($xpath[0]['href'], $image_url_friendly, 'The image had its spaces replaces with "%20".'); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that a default value on an image field will be output correctly. + */ + function testNodeFieldDefault() { + // Generate a test image file object. + $image = $this->generateImageFile(); + $image_url = file_create_url($image->uri); + + // Dump out the file object, to aid with debugging. + $this->verbose('
' . print_r($image, TRUE) . '
'); + + // Update the article-image default settings to use the new image field. + $entity_type = 'node'; + $bundle = 'article'; + $field_name = 'field_image'; + $instance = field_info_instance($entity_type, $field_name, $bundle); + $instance['settings']['default_image'] = $image->fid; + field_update_instance($instance); + + // Create an example node. + $args = [ + 'type' => 'article', + ]; + $node = $this->drupalCreateNode($args); + + // Update the config. + $config = metatag_config_load('node'); + $config->config['image_src']['value'] = '[node:field_image]'; + metatag_config_save($config); + + // Load the node page. + $this->drupalGet('node/' . $node->nid); + $this->assertResponse(200); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual($xpath[0]['href'], $image_url, "The image_src meta tag was found with the field's default image."); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that a file on an image field will be output correctly. + */ + function testNodeFieldValue() { + // Update the 'content' config to use the field_image field as the + // image_src meta tag. + $config = metatag_config_load('node'); + $config->config['image_src']['value'] = '[node:field_image]'; + metatag_config_save($config); + + // Generate a test image file object. + $image = $this->generateImageFile(); + $image_url = file_create_url($image->uri); + + // Dump out the file object, to aid with debugging. + $this->verbose('
' . print_r($image, TRUE) . '
'); + + // Create an example node. + $args = [ + 'type' => 'article', + 'field_image' => [ + LANGUAGE_NONE => [ + ['fid' => $image->fid], + ], + ], + ]; + $node = $this->drupalCreateNode($args); + + // Forcibly reload the node, to avoid working with a cached version. + $node = node_load($node->nid, NULL, TRUE); + $this->verbose('

Node:

' . print_r($node, TRUE) . '
'); + + // Load the node page. + $this->drupalGet('node/' . $node->nid); + $this->assertResponse(200); + + // Confirm that the image_src meta tag has the expected values. + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'One image_src meta tag found.'); + $this->assertEqual($xpath[0]['href'], $image_url, "The image_src meta tag was found with the node's image field's value."); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that when using a file field that allows multiple values, only the + * first item will be used when outputting a single meta tag. + */ + function testNodeFieldValueNotMultiple() { + // Update the 'content' config to use the field_image field as the + // image_src meta tag. + $config = metatag_config_load('node'); + $config->config['image_src']['value'] = '[node:field_image]'; + metatag_config_save($config); + + // Update the image field to allow unlimited items. + $field_name = 'field_image'; + $field = field_info_field($field_name); + $field['cardinality'] = FIELD_CARDINALITY_UNLIMITED; + field_update_field($field); + + // Generate a test image file object. + $image1 = $this->generateImageFile(); + $image1_url = file_create_url($image1->uri); + $image2 = $this->generateImageFile(); + $image2_url = file_create_url($image2->uri); + + // Dump out the file objects, to aid with debugging. + $this->verbose('

Image #1

' . print_r($image1, TRUE) . '
'); + $this->verbose('

Image #2

' . print_r($image2, TRUE) . '
'); + + // Create an example node. + $args = [ + 'type' => 'article', + 'field_image' => [ + LANGUAGE_NONE => [ + ['fid' => $image1->fid], + ['fid' => $image2->fid], + ], + ], + ]; + $node = $this->drupalCreateNode($args); + + // Forcibly reload the node, to avoid working with a cached version. + $node = node_load($node->nid, NULL, TRUE); + $this->verbose('

Node:

' . print_r($node, TRUE) . '
'); + + // Load the node page. + $this->drupalGet('node/' . $node->nid); + $this->assertResponse(200); + + // Confirm that the image_src meta tag has the expected values. + + $xpath = $this->xpath("//link[@rel='image_src']"); + $this->assertEqual(count($xpath), 1, 'Only one image_src meta tag found.'); + $this->assertEqual($xpath[0]['href'], $image1_url, "The image_src meta tag was found with the node's image field's first value."); + $this->assertNotEqual($xpath[0]['href'], $image2_url, "The image_src meta tag does not contain the node's image field's second value."); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['href']); + $this->assertResponse(200, "The image_src meta tag's value could be loaded."); + } + + /** + * Confirm that when using a file field that allows multiple values, that + * multiple images can be used and then it will result in multiple meta tags. + */ + function testNodeFieldValueMultiple() { + // Update the 'content' config to use the field_image field as the + // image_src meta tag. + $config = metatag_config_load('node'); + $config->config['og:image']['value'] = '[node:field_image]'; + metatag_config_save($config); + + // Update the image field to allow unlimited items. + $field_name = 'field_image'; + $field = field_info_field($field_name); + $field['cardinality'] = FIELD_CARDINALITY_UNLIMITED; + field_update_field($field); + + // Generate a test image file object. + $image1 = $this->generateImageFile(); + $image1_url = file_create_url($image1->uri); + $image2 = $this->generateImageFile(); + $image2_url = file_create_url($image2->uri); + + // Dump out the file objects, to aid with debugging. + $this->verbose('

Image #1

' . print_r($image1, TRUE) . '
'); + $this->verbose('

Image #2

' . print_r($image2, TRUE) . '
'); + + // Create an example node. + $args = [ + 'type' => 'article', + 'field_image' => [ + LANGUAGE_NONE => [ + ['fid' => $image1->fid], + ['fid' => $image2->fid], + ], + ], + ]; + $node = $this->drupalCreateNode($args); + + // Forcibly reload the node, to avoid working with a cached version. + $node = node_load($node->nid, NULL, TRUE); + $this->verbose('

Node:

' . print_r($node, TRUE) . '
'); + + // Load the node page. + $this->drupalGet('node/' . $node->nid); + $this->assertResponse(200); + + // Confirm that the og:image meta tags have the expected values. + $xpath = $this->xpath("//meta[@property='og:image']"); + $this->assertEqual(count($xpath), 2, 'Two og:image meta tags were found.'); + $this->assertEqual($xpath[0]['content'], $image1_url, "The first og:image meta tag has the correct image."); + $this->assertEqual($xpath[1]['content'], $image2_url, "The second og:image meta tag has the correct image."); + + // Confirm the file could be loaded. + $this->drupalGet($xpath[0]['content']); + $this->assertResponse(200, "The first og:image meta tag's value could be loaded."); + $this->drupalGet($xpath[1]['content']); + $this->assertResponse(200, "The second og:image meta tag's value could be loaded."); + } + + /** + * Create an image of a specific size & type. + * + * @param string $image_size + * The size of the requested image in 'XxY' format; defaults to '200x200'. + * @param string $format + * The image format to use, defaults to 'png'. + * + * @return string + * The URL to a public file. + */ + function generateImage($image_size = '200x200', $format = 'png') { + // Only proceed if the Devel Generate module is installed. + if (module_exists('devel_generate')) { + // Load the Devel Generate image generator logic. + module_load_include('inc', 'devel_generate', 'image.devel_generate'); + + $image_format = 'png'; + $image_size = '200x200'; + $temp_image = devel_generate_image($image_format, $image_size, $image_size); + + return file_unmanaged_move($temp_image, 'public://'); + } + else { + $this->error('The Devel Generate module is not enabled, it must be added to the $modules array in the setUp() method for this test class.'); + } + } + + /** + * Create an image file object of a specific size & type. + * + * @param string + * The size of the requested image in 'XxY' format; defaults to '200x200'. + * @param string + * The image format to use, defaults to 'png'. + * + * @return object + * The file object for the generated image. + */ + function generateImageFile($image_size = '200x200', $format = 'png') { + // Generate a test image. + $image_uri = $this->generateImage(); + + // Create a file object for this image. + $file = new StdClass(); + $file->fid = NULL; + $file->uid = 1; + $file->uri = $image_uri; + $file->filemime = file_get_mimetype($image_uri); + $file->filesize = filesize($image_uri); + $file->status = 1; + $file->timestamp = filemtime($image_uri); + $saved_file = file_save($file); + + return $saved_file; + } + +}