Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7d61e75f | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
7d61e75f TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * Mail utils for use during unit testing to allow retrieval | |
14 | * and examination of 'sent' emails. | |
15 | * | |
16 | * Basic usage: | |
17 | * | |
18 | * $mut = new CiviMailUtils( $this, true ); //true automatically starts spooling | |
19 | * ... do stuff ... | |
20 | * $msg = $mut->getMostRecentEmail( 'raw' ); // or 'ezc' to get an ezc mail object | |
21 | * ... assert stuff about $msg ... | |
22 | * $mut->stop(); | |
23 | * | |
24 | * | |
25 | * @package CiviCRM | |
26 | */ | |
27 | ||
4cbe18b8 EM |
28 | /** |
29 | * Class CiviMailUtils | |
30 | */ | |
a6439b6a | 31 | class CiviMailUtils extends PHPUnit\Framework\TestCase { |
6a488035 TO |
32 | |
33 | /** | |
1d3260ea SL |
34 | * Current outbound email option |
35 | * @var mixed | |
6a488035 TO |
36 | */ |
37 | protected $_outBound_option = NULL; | |
38 | ||
6a488035 | 39 | /** |
eceb18cc | 40 | * Constructor. |
6a488035 | 41 | * |
ef7d4bd1 | 42 | * @param CiviUnitTestCase $unit_test The currently running test |
e16033b4 TO |
43 | * @param bool $startImmediately |
44 | * Start writing to db now or wait until start() is called. | |
6a488035 | 45 | */ |
00be9182 | 46 | public function __construct(&$unit_test, $startImmediately = TRUE) { |
70520a0b CW |
47 | $this->_ut = $unit_test; |
48 | ||
6a488035 TO |
49 | if ($startImmediately) { |
50 | $this->start(); | |
51 | } | |
52 | } | |
53 | ||
f816b68f | 54 | /** |
55 | * Clean up after test. | |
56 | * | |
57 | * @throws \CRM_Core_Exception | |
58 | */ | |
59 | public function __destruct() { | |
60 | $this->stop(); | |
61 | $this->clearMessages(); | |
62 | } | |
63 | ||
6a488035 | 64 | /** |
eceb18cc | 65 | * Start writing emails to db instead of current option. |
6a488035 | 66 | */ |
00be9182 | 67 | public function start() { |
ef7d4bd1 | 68 | // save current setting for outbound option, then change it |
69 | $mailingBackend = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, | |
70 | 'mailing_backend' | |
71 | ); | |
6a488035 | 72 | |
ef7d4bd1 | 73 | $this->_outBound_option = $mailingBackend['outBound_option']; |
74 | $mailingBackend['outBound_option'] = CRM_Mailing_Config::OUTBOUND_OPTION_REDIRECT_TO_DB; | |
6a488035 | 75 | |
ef7d4bd1 | 76 | Civi::settings()->set('mailing_backend', $mailingBackend); |
6a488035 | 77 | |
ef7d4bd1 | 78 | $mailingBackend = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, |
79 | 'mailing_backend' | |
80 | ); | |
6a488035 TO |
81 | } |
82 | ||
00be9182 | 83 | public function stop() { |
ef7d4bd1 | 84 | $mailingBackend = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, |
85 | 'mailing_backend' | |
86 | ); | |
6a488035 | 87 | |
ef7d4bd1 | 88 | $mailingBackend['outBound_option'] = $this->_outBound_option; |
6a488035 | 89 | |
ef7d4bd1 | 90 | Civi::settings()->set('mailing_backend', $mailingBackend); |
6a488035 TO |
91 | } |
92 | ||
4cbe18b8 EM |
93 | /** |
94 | * @param string $type | |
95 | * | |
96 | * @return ezcMail|string | |
97 | */ | |
00be9182 | 98 | public function getMostRecentEmail($type = 'raw') { |
6a488035 TO |
99 | $msg = ''; |
100 | ||
ef7d4bd1 | 101 | $dao = CRM_Core_DAO::executeQuery('SELECT headers, body FROM civicrm_mailing_spool ORDER BY id DESC LIMIT 1'); |
102 | if ($dao->fetch()) { | |
103 | $msg = $dao->headers . "\n\n" . $dao->body; | |
6a488035 TO |
104 | } |
105 | ||
106 | switch ($type) { | |
107 | case 'raw': | |
108 | // nothing to do | |
109 | break; | |
6c6e6187 | 110 | |
6a488035 TO |
111 | case 'ezc': |
112 | $msg = $this->convertToEzc($msg); | |
113 | break; | |
114 | } | |
115 | return $msg; | |
116 | } | |
117 | ||
118 | /** | |
e16033b4 TO |
119 | * @param string $type |
120 | * 'raw'|'ezc'. | |
cbdcc634 | 121 | * |
e88f4fee | 122 | * @throws CRM_Core_Exception |
123 | * | |
6a488035 TO |
124 | * @return array(ezcMail)|array(string) |
125 | */ | |
00be9182 | 126 | public function getAllMessages($type = 'raw') { |
e88f4fee | 127 | $msgs = []; |
6a488035 | 128 | |
e88f4fee | 129 | $dao = CRM_Core_DAO::executeQuery('SELECT headers, body FROM civicrm_mailing_spool ORDER BY id'); |
130 | while ($dao->fetch()) { | |
131 | $msgs[] = $dao->headers . "\n\n" . $dao->body; | |
6a488035 TO |
132 | } |
133 | ||
134 | switch ($type) { | |
135 | case 'raw': | |
136 | // nothing to do | |
137 | break; | |
6c6e6187 | 138 | |
6a488035 TO |
139 | case 'ezc': |
140 | foreach ($msgs as $i => $msg) { | |
141 | $msgs[$i] = $this->convertToEzc($msg); | |
142 | } | |
143 | break; | |
144 | } | |
145 | ||
146 | return $msgs; | |
147 | } | |
148 | ||
6a488035 TO |
149 | /* |
150 | * Utility functions (previously part of CiviUnitTestCase) | |
151 | * Included for backward compatibility with existing tests. | |
152 | */ | |
153 | ||
154 | /** | |
eceb18cc | 155 | * Check contents of mail log. |
77b97be7 | 156 | * |
e16033b4 TO |
157 | * @param array $strings |
158 | * Strings that should be included. | |
159 | * @param array $absentStrings | |
160 | * Strings that should not be included. | |
77b97be7 | 161 | * @param string $prefix |
6a488035 | 162 | * |
77b97be7 | 163 | * @return \ezcMail|string |
6a488035 | 164 | */ |
affcc9d2 | 165 | public function checkMailLog($strings, $absentStrings = [], $prefix = '') { |
6a488035 | 166 | $mail = $this->getMostRecentEmail('raw'); |
481312d9 | 167 | return $this->checkMailForStrings($strings, $absentStrings, $prefix, $mail); |
168 | } | |
169 | ||
170 | /** | |
171 | * Check contents of mail log. | |
172 | * | |
173 | * @param array $strings | |
174 | * Strings that should be included. | |
175 | * @param array $absentStrings | |
176 | * Strings that should not be included. | |
177 | * @param string $prefix | |
178 | * | |
179 | * @return \ezcMail|string | |
180 | */ | |
affcc9d2 | 181 | public function checkAllMailLog($strings, $absentStrings = [], $prefix = '') { |
481312d9 | 182 | $mails = $this->getAllMessages('raw'); |
183 | $mail = implode(',', $mails); | |
184 | return $this->checkMailForStrings($strings, $absentStrings, $prefix, $mail); | |
6a488035 TO |
185 | } |
186 | ||
187 | /** | |
eceb18cc | 188 | * Check that mail log is empty. |
1e1fdcf6 | 189 | * @param string $prefix |
6a488035 | 190 | */ |
00be9182 | 191 | public function assertMailLogEmpty($prefix = '') { |
6a488035 TO |
192 | $mail = $this->getMostRecentEmail('raw'); |
193 | $this->_ut->assertEmpty($mail, 'mail sent when it should not have been ' . $prefix); | |
194 | } | |
195 | ||
196 | /** | |
197 | * Assert that $expectedRecipients (and no else) have received emails | |
198 | * | |
e16033b4 TO |
199 | * @param array $expectedRecipients |
200 | * Array($msgPos => array($recipPos => $emailAddr)). | |
6a488035 | 201 | */ |
00be9182 | 202 | public function assertRecipients($expectedRecipients) { |
affcc9d2 | 203 | $recipients = []; |
6a488035 TO |
204 | foreach ($this->getAllMessages('ezc') as $message) { |
205 | $recipients[] = CRM_Utils_Array::collect('email', $message->to); | |
206 | } | |
11f535e4 TO |
207 | $cmp = function($a, $b) { |
208 | if ($a[0] == $b[0]) { | |
209 | return 0; | |
210 | } | |
211 | return ($a[0] < $b[0]) ? 1 : -1; | |
212 | }; | |
213 | usort($recipients, $cmp); | |
214 | usort($expectedRecipients, $cmp); | |
6a488035 TO |
215 | $this->_ut->assertEquals( |
216 | $expectedRecipients, | |
217 | $recipients, | |
218 | "Incorrect recipients: " . print_r(array('expected' => $expectedRecipients, 'actual' => $recipients), TRUE) | |
219 | ); | |
220 | } | |
221 | ||
f8c3594b TO |
222 | /** |
223 | * Assert that $expectedSubjects (and no other subjects) were sent. | |
224 | * | |
225 | * @param array $expectedSubjects | |
226 | * Array(string $subj). | |
227 | */ | |
228 | public function assertSubjects($expectedSubjects) { | |
affcc9d2 | 229 | $subjects = []; |
f8c3594b TO |
230 | foreach ($this->getAllMessages('ezc') as $message) { |
231 | /** @var ezcMail $message */ | |
232 | $subjects[] = $message->subject; | |
233 | } | |
234 | sort($subjects); | |
235 | sort($expectedSubjects); | |
236 | $this->_ut->assertEquals( | |
237 | $expectedSubjects, | |
238 | $subjects, | |
239 | "Incorrect subjects: " . print_r(array('expected' => $expectedSubjects, 'actual' => $subjects), TRUE) | |
240 | ); | |
241 | } | |
242 | ||
6a488035 | 243 | /** |
eceb18cc | 244 | * Remove any sent messages from the log. |
aa1febb5 | 245 | * |
246 | * @param int $limit | |
b13d4a61 | 247 | * How many recent messages to remove, defaults to 0 (all). |
aa1febb5 | 248 | * |
1e0f58c7 | 249 | * @throws \CRM_Core_Exception |
6a488035 | 250 | */ |
b13d4a61 | 251 | public function clearMessages($limit = 0) { |
ef7d4bd1 | 252 | $sql = 'DELETE FROM civicrm_mailing_spool ORDER BY id DESC'; |
253 | if ($limit) { | |
254 | $sql .= ' LIMIT ' . $limit; | |
6a488035 | 255 | } |
ef7d4bd1 | 256 | CRM_Core_DAO::executeQuery($sql); |
6a488035 TO |
257 | } |
258 | ||
259 | /** | |
e16033b4 TO |
260 | * @param string $msg |
261 | * Email header and body. | |
6a488035 TO |
262 | * @return ezcMail |
263 | */ | |
264 | private function convertToEzc($msg) { | |
14d3f751 | 265 | $set = new ezcMailVariableSet($msg); |
6a488035 TO |
266 | $parser = new ezcMailParser(); |
267 | $mail = $parser->parseMail($set); | |
268 | $this->_ut->assertNotEmpty($mail, 'Cannot parse mail'); | |
269 | return $mail[0]; | |
270 | } | |
96025800 | 271 | |
481312d9 | 272 | /** |
da508f63 | 273 | * @param array $strings |
481312d9 | 274 | * @param $absentStrings |
275 | * @param $prefix | |
276 | * @param $mail | |
277 | * @return mixed | |
278 | */ | |
e9cde327 | 279 | public function checkMailForStrings(array $strings, $absentStrings, $prefix, $mail) { |
481312d9 | 280 | foreach ($strings as $string) { |
e9cde327 | 281 | $this->_ut->assertStringContainsString($string, $mail, "$string . not found in $mail $prefix"); |
481312d9 | 282 | } |
283 | foreach ($absentStrings as $string) { | |
fe7f4414 | 284 | $this->_ut->assertEmpty(strstr($mail, $string), "$string incorrectly found in $mail $prefix"); |
481312d9 | 285 | } |
286 | return $mail; | |
287 | } | |
288 | ||
6a488035 | 289 | } |