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