AssertMailTrait.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. namespace Drupal\Core\Test;
  3. use Drupal\Component\Render\FormattableMarkup;
  4. /**
  5. * Provides methods for testing emails sent during test runs.
  6. */
  7. trait AssertMailTrait {
  8. /**
  9. * Gets an array containing all emails sent during this test case.
  10. *
  11. * @param array $filter
  12. * An array containing key/value pairs used to filter the emails that are
  13. * returned.
  14. *
  15. * @return array
  16. * An array containing email messages captured during the current test.
  17. */
  18. protected function getMails(array $filter = []) {
  19. $captured_emails = $this->container->get('state')->get('system.test_mail_collector', []);
  20. $filtered_emails = [];
  21. foreach ($captured_emails as $message) {
  22. foreach ($filter as $key => $value) {
  23. if (!isset($message[$key]) || $message[$key] != $value) {
  24. continue 2;
  25. }
  26. }
  27. $filtered_emails[] = $message;
  28. }
  29. return $filtered_emails;
  30. }
  31. /**
  32. * Asserts that the most recently sent email message has the given value.
  33. *
  34. * The field in $name must have the content described in $value.
  35. *
  36. * @param string $name
  37. * Name of field or message property to assert. Examples: subject, body,
  38. * id, ...
  39. * @param string $value
  40. * Value of the field to assert.
  41. * @param string $message
  42. * (optional) A message to display with the assertion. Do not translate
  43. * messages: use \Drupal\Component\Render\FormattableMarkup to embed
  44. * variables in the message text, not t(). If left blank, a default message
  45. * will be displayed.
  46. * @param string $group
  47. * (optional) The group this message is in, which is displayed in a column
  48. * in test output. Use 'Debug' to indicate this is debugging output. Do not
  49. * translate this string. Defaults to 'Email'; most tests do not override
  50. * this default.
  51. *
  52. * @return bool
  53. * TRUE on pass, FALSE on fail.
  54. */
  55. protected function assertMail($name, $value = '', $message = '', $group = 'Email') {
  56. $captured_emails = $this->container->get('state')->get('system.test_mail_collector') ?: [];
  57. $email = end($captured_emails);
  58. return $this->assertTrue($email && isset($email[$name]) && $email[$name] == $value, $message, $group);
  59. }
  60. /**
  61. * Asserts that the most recently sent email message has the string in it.
  62. *
  63. * @param string $field_name
  64. * Name of field or message property to assert: subject, body, id, ...
  65. * @param string $string
  66. * String to search for.
  67. * @param int $email_depth
  68. * Number of emails to search for string, starting with most recent.
  69. * @param string $message
  70. * (optional) A message to display with the assertion. Do not translate
  71. * messages: use \Drupal\Component\Render\FormattableMarkup to embed
  72. * variables in the message text, not t(). If left blank, a default message
  73. * will be displayed.
  74. * @param string $group
  75. * (optional) The group this message is in, which is displayed in a column
  76. * in test output. Use 'Debug' to indicate this is debugging output. Do not
  77. * translate this string. Defaults to 'Other'; most tests do not override
  78. * this default.
  79. *
  80. * @return bool
  81. * TRUE on pass, FALSE on fail.
  82. */
  83. protected function assertMailString($field_name, $string, $email_depth, $message = '', $group = 'Other') {
  84. $mails = $this->getMails();
  85. $string_found = FALSE;
  86. // Cast MarkupInterface objects to string.
  87. $string = (string) $string;
  88. for ($i = count($mails) - 1; $i >= count($mails) - $email_depth && $i >= 0; $i--) {
  89. $mail = $mails[$i];
  90. // Normalize whitespace, as we don't know what the mail system might have
  91. // done. Any run of whitespace becomes a single space.
  92. $normalized_mail = preg_replace('/\s+/', ' ', $mail[$field_name]);
  93. $normalized_string = preg_replace('/\s+/', ' ', $string);
  94. $string_found = (FALSE !== strpos($normalized_mail, $normalized_string));
  95. if ($string_found) {
  96. break;
  97. }
  98. }
  99. if (!$message) {
  100. $message = new FormattableMarkup('Expected text found in @field of email message: "@expected".', ['@field' => $field_name, '@expected' => $string]);
  101. }
  102. return $this->assertTrue($string_found, $message, $group);
  103. }
  104. /**
  105. * Asserts that the most recently sent email message has the pattern in it.
  106. *
  107. * @param string $field_name
  108. * Name of field or message property to assert: subject, body, id, ...
  109. * @param string $regex
  110. * Pattern to search for.
  111. * @param string $message
  112. * (optional) A message to display with the assertion. Do not translate
  113. * messages: use \Drupal\Component\Render\FormattableMarkup to embed
  114. * variables in the message text, not t(). If left blank, a default message
  115. * will be displayed.
  116. * @param string $group
  117. * (optional) The group this message is in, which is displayed in a column
  118. * in test output. Use 'Debug' to indicate this is debugging output. Do not
  119. * translate this string. Defaults to 'Other'; most tests do not override
  120. * this default.
  121. *
  122. * @return bool
  123. * TRUE on pass, FALSE on fail.
  124. */
  125. protected function assertMailPattern($field_name, $regex, $message = '', $group = 'Other') {
  126. $mails = $this->getMails();
  127. $mail = end($mails);
  128. $regex_found = preg_match("/$regex/", $mail[$field_name]);
  129. if (!$message) {
  130. $message = new FormattableMarkup('Expected text found in @field of email message: "@expected".', ['@field' => $field_name, '@expected' => $regex]);
  131. }
  132. return $this->assertTrue($regex_found, $message, $group);
  133. }
  134. /**
  135. * Outputs to verbose the most recent $count emails sent.
  136. *
  137. * @param int $count
  138. * Optional number of emails to output.
  139. */
  140. protected function verboseEmail($count = 1) {
  141. $mails = $this->getMails();
  142. for ($i = count($mails) - 1; $i >= count($mails) - $count && $i >= 0; $i--) {
  143. $mail = $mails[$i];
  144. $this->verbose('Email:<pre>' . print_r($mail, TRUE) . '</pre>');
  145. }
  146. }
  147. }