You are here

public function MailTest::testRenderedElementsUseAbsolutePaths in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/system/tests/src/Kernel/Mail/MailTest.php \Drupal\Tests\system\Kernel\Mail\MailTest::testRenderedElementsUseAbsolutePaths()

Checks that mails built from render arrays contain absolute paths.

By default Drupal uses relative paths for images and links. When sending emails, absolute paths should be used instead.

File

core/modules/system/tests/src/Kernel/Mail/MailTest.php, line 276

Class

MailTest
Performs tests on the pluggable mailing framework.

Namespace

Drupal\Tests\system\Kernel\Mail

Code

public function testRenderedElementsUseAbsolutePaths() {
  $language_interface = \Drupal::languageManager()
    ->getCurrentLanguage();
  $this
    ->configureDefaultMailInterface('test_html_mail_collector');

  // Fetch the hostname and port for matching against.
  $http_host = \Drupal::request()
    ->getSchemeAndHttpHost();

  // Random generator.
  $random = new Random();
  $image_name = $random
    ->name();
  $test_base_url = 'http://localhost';
  $this
    ->setSetting('file_public_base_url', $test_base_url);
  $filepath = \Drupal::service('file_system')
    ->createFilename("{$image_name}.png", '');
  $directory_uri = 'public://' . dirname($filepath);
  \Drupal::service('file_system')
    ->prepareDirectory($directory_uri, FileSystemInterface::CREATE_DIRECTORY);

  // Create an image file.
  $file = File::create([
    'uri' => "public://{$image_name}.png",
    'filename' => "{$image_name}.png",
  ]);
  $file
    ->save();
  $base_path = base_path();
  $path_pairs = [
    'root relative' => [
      $file
        ->getFileUri(),
      "{$http_host}{$base_path}{$image_name}.png",
    ],
    'protocol relative' => [
      '//example.com/image.png',
      '//example.com/image.png',
    ],
    'absolute' => [
      'http://example.com/image.png',
      'http://example.com/image.png',
    ],
  ];

  // Test images.
  foreach ($path_pairs as $test_type => $paths) {
    list($input_path, $expected_path) = $paths;

    // Reset the state variable that holds sent messages.
    \Drupal::state()
      ->set('system.test_mail_collector', []);

    // Build the render array.
    $render = [
      '#theme' => 'image',
      '#uri' => $input_path,
    ];
    $expected_html = "<img src=\"{$expected_path}\" alt=\"\" />";

    // Send a test message that mail_cancel_test_mail_alter should cancel.
    \Drupal::service('plugin.manager.mail')
      ->mail('mail_html_test', 'render_from_message_param', 'relative_url@example.com', $language_interface
      ->getId(), [
      'message' => $render,
    ]);

    // Retrieve sent message.
    $captured_emails = \Drupal::state()
      ->get('system.test_mail_collector');
    $sent_message = end($captured_emails);

    // Wrap the expected HTML and assert.
    $expected_html = MailFormatHelper::wrapMail($expected_html);
    $this
      ->assertSame($expected_html, $sent_message['body'], "Asserting that {$test_type} paths are converted properly.");
  }

  // Test links.
  $path_pairs = [
    'root relative' => [
      Url::fromUserInput('/path/to/something'),
      "{$http_host}{$base_path}path/to/something",
    ],
    'protocol relative' => [
      Url::fromUri('//example.com/image.png'),
      '//example.com/image.png',
    ],
    'absolute' => [
      Url::fromUri('http://example.com/image.png'),
      'http://example.com/image.png',
    ],
  ];
  foreach ($path_pairs as $paths) {
    list($input_path, $expected_path) = $paths;

    // Reset the state variable that holds sent messages.
    \Drupal::state()
      ->set('system.test_mail_collector', []);

    // Build the render array.
    $render = [
      '#title' => 'Link',
      '#type' => 'link',
      '#url' => $input_path,
    ];
    $expected_html = "<a href=\"{$expected_path}\">Link</a>";

    // Send a test message that mail_cancel_test_mail_alter should cancel.
    \Drupal::service('plugin.manager.mail')
      ->mail('mail_html_test', 'render_from_message_param', 'relative_url@example.com', $language_interface
      ->getId(), [
      'message' => $render,
    ]);

    // Retrieve sent message.
    $captured_emails = \Drupal::state()
      ->get('system.test_mail_collector');
    $sent_message = end($captured_emails);

    // Wrap the expected HTML and assert.
    $expected_html = MailFormatHelper::wrapMail($expected_html);
    $this
      ->assertSame($expected_html, $sent_message['body']);
  }
}