Fixes for Activity import
[civicrm-core.git] / tests / phpunit / CiviTest / CiviMailUtils.php
CommitLineData
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 31class 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}