You are here

public function MailTest::testFromAndReplyToHeader in Drupal 8

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

Checks the From: and Reply-to: headers.

File

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

Class

MailTest
Performs tests on the pluggable mailing framework.

Namespace

Drupal\Tests\system\Kernel\Mail

Code

public function testFromAndReplyToHeader() {
  $language = \Drupal::languageManager()
    ->getCurrentLanguage();

  // Set required site configuration.
  $this
    ->config('system.site')
    ->set('mail', 'mailtest@example.com')
    ->set('name', 'Drupal')
    ->save();

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

  // Send an email with a reply-to address specified.
  $from_email = 'Drupal <mailtest@example.com>';
  $reply_email = 'someone_else@example.com';
  \Drupal::service('plugin.manager.mail')
    ->mail('mail_cancel_test', 'from_test', 'from_test@example.com', $language, [], $reply_email);

  // Test that the reply-to email is just the email and not the site name
  // and default sender email.
  $captured_emails = \Drupal::state()
    ->get('system.test_mail_collector');
  $sent_message = end($captured_emails);

  // Message is sent from the site email account.
  $this
    ->assertEquals($from_email, $sent_message['headers']['From']);

  // Message reply-to headers are set.
  $this
    ->assertEquals($reply_email, $sent_message['headers']['Reply-to']);

  // Errors-to header must not be set, it is deprecated.
  $this
    ->assertFalse(isset($sent_message['headers']['Errors-To']));

  // Test that long site names containing characters that need MIME encoding
  // works as expected.
  $this
    ->config('system.site')
    ->set('name', 'Drépal this is a very long test sentence to test what happens with very long site names')
    ->save();

  // Send an email and check that the From-header contains the site name.
  \Drupal::service('plugin.manager.mail')
    ->mail('mail_cancel_test', 'from_test', 'from_test@example.com', $language);
  $captured_emails = \Drupal::state()
    ->get('system.test_mail_collector');
  $sent_message = end($captured_emails);

  // From header is correctly encoded.
  $this
    ->assertEquals('=?UTF-8?B?RHLDqXBhbCB0aGlzIGlzIGEgdmVyeSBsb25nIHRlc3Qgc2VudGVuY2UgdG8gdGU=?= <mailtest@example.com>', $sent_message['headers']['From']);

  // From header is correctly encoded.
  $this
    ->assertEquals('Drépal this is a very long test sentence to te <mailtest@example.com>', Unicode::mimeHeaderDecode($sent_message['headers']['From']));
  $this
    ->assertFalse(isset($sent_message['headers']['Reply-to']), 'Message reply-to is not set if not specified.');

  // Errors-to header must not be set, it is deprecated.
  $this
    ->assertFalse(isset($sent_message['headers']['Errors-To']));

  // Test RFC-2822 rules are respected for 'display-name' component of
  // 'From:' header. Specials characters are not allowed, so randomly add one
  // of them to the site name and check the string is wrapped in quotes. Also
  // hardcode some double-quotes and backslash to validate these are escaped
  // properly too.
  $specials = '()<>[]:;@\\,."';
  $site_name = 'Drupal' . $specials[rand(0, strlen($specials) - 1)] . ' "si\\te"';
  $this
    ->config('system.site')
    ->set('name', $site_name)
    ->save();

  // Send an email and check that the From-header contains the site name
  // within double-quotes. Also make sure double-quotes and "\" are escaped.
  \Drupal::service('plugin.manager.mail')
    ->mail('mail_cancel_test', 'from_test', 'from_test@example.com', $language);
  $captured_emails = \Drupal::state()
    ->get('system.test_mail_collector');
  $sent_message = end($captured_emails);
  $escaped_site_name = str_replace([
    '\\',
    '"',
  ], [
    '\\\\',
    '\\"',
  ], $site_name);

  // From header is correctly quoted.
  $this
    ->assertEquals('"' . $escaped_site_name . '" <mailtest@example.com>', $sent_message['headers']['From']);

  // Make sure display-name is not quoted nor escaped if part on an encoding.
  $site_name = 'Drépal, "si\\te"';
  $this
    ->config('system.site')
    ->set('name', $site_name)
    ->save();

  // Send an email and check that the From-header contains the site name.
  \Drupal::service('plugin.manager.mail')
    ->mail('mail_cancel_test', 'from_test', 'from_test@example.com', $language);
  $captured_emails = \Drupal::state()
    ->get('system.test_mail_collector');
  $sent_message = end($captured_emails);

  // From header is correctly encoded.
  $this
    ->assertEquals('=?UTF-8?B?RHLDqXBhbCwgInNpXHRlIg==?= <mailtest@example.com>', $sent_message['headers']['From']);

  // From header is correctly encoded.
  $this
    ->assertEquals($site_name . ' <mailtest@example.com>', Unicode::mimeHeaderDecode($sent_message['headers']['From']));
}