Commit | Line | Data |
---|---|---|
07c09ae4 EM |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7d61e75f | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
07c09ae4 | 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 | | |
07c09ae4 EM |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
12 | /** | |
13 | * File for the CiviCRM APIv3 job functions | |
14 | * | |
15 | * @package CiviCRM_APIv3 | |
16 | * @subpackage API_Job | |
17 | * | |
ca5cec67 | 18 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
07c09ae4 EM |
19 | * @version $Id: Job.php 30879 2010-11-22 15:45:55Z shot $ |
20 | * | |
21 | */ | |
0eea664b | 22 | |
07c09ae4 EM |
23 | /** |
24 | * Class api_v3_JobTest | |
acb109b7 | 25 | * @group headless |
b4a332a9 | 26 | * @group civimail |
07c09ae4 EM |
27 | */ |
28 | class api_v3_JobProcessMailingTest extends CiviUnitTestCase { | |
29 | protected $_apiversion = 3; | |
30 | ||
31 | public $DBResetRequired = FALSE; | |
32 | public $_entity = 'Job'; | |
9099cab3 | 33 | public $_params = []; |
07c09ae4 EM |
34 | private $_groupID; |
35 | private $_email; | |
36 | ||
d667a9ba TO |
37 | protected $defaultSettings; |
38 | ||
07c09ae4 EM |
39 | /** |
40 | * @var CiviMailUtils | |
41 | */ | |
42 | private $_mut; | |
43 | ||
00be9182 | 44 | public function setUp() { |
d667a9ba | 45 | $this->cleanupMailingTest(); |
07c09ae4 | 46 | parent::setUp(); |
39b959db SL |
47 | // DGW |
48 | CRM_Mailing_BAO_MailingJob::$mailsProcessed = 0; | |
07c09ae4 EM |
49 | $this->_groupID = $this->groupCreate(); |
50 | $this->_email = 'test@test.test'; | |
9099cab3 | 51 | $this->_params = [ |
07c09ae4 | 52 | 'subject' => 'Accidents in cars cause children', |
21b09c13 | 53 | 'body_text' => 'BEWARE children need regular infusions of toys. Santa knows your {domain.address}. There is no {action.optOutUrl}.', |
07c09ae4 EM |
54 | 'name' => 'mailing name', |
55 | 'created_id' => 1, | |
9099cab3 | 56 | 'groups' => ['include' => [$this->_groupID]], |
5f445749 | 57 | 'scheduled_date' => 'now', |
9099cab3 CW |
58 | ]; |
59 | $this->defaultSettings = [ | |
39b959db SL |
60 | // int, #mailings to send |
61 | 'mailings' => 1, | |
62 | // int, #contacts to receive mailing | |
63 | 'recipients' => 20, | |
64 | // int, #concurrent cron jobs | |
65 | 'workers' => 1, | |
66 | // int, #times to spawn all the workers | |
67 | 'iterations' => 1, | |
68 | // int, #extra seconds each cron job should hold lock | |
69 | 'lockHold' => 0, | |
70 | // int, max# recipients to send in a given cron run | |
71 | 'mailerBatchLimit' => 0, | |
72 | // int, max# concurrent jobs | |
73 | 'mailerJobsMax' => 0, | |
74 | // int, max# recipients in each job | |
75 | 'mailerJobSize' => 0, | |
76 | // int, microseconds separating messages | |
77 | 'mailThrottleTime' => 0, | |
9099cab3 | 78 | ]; |
481a74f4 | 79 | $this->_mut = new CiviMailUtils($this, TRUE); |
9099cab3 | 80 | $this->callAPISuccess('mail_settings', 'get', ['api.mail_settings.create' => ['domain' => 'chaos.org']]); |
07c09ae4 EM |
81 | } |
82 | ||
83 | /** | |
07c09ae4 | 84 | */ |
00be9182 | 85 | public function tearDown() { |
d667a9ba | 86 | //$this->_mut->clearMessages(); |
07c09ae4 | 87 | $this->_mut->stop(); |
07c09ae4 | 88 | CRM_Utils_Hook::singleton()->reset(); |
39b959db SL |
89 | // DGW |
90 | CRM_Mailing_BAO_MailingJob::$mailsProcessed = 0; | |
d667a9ba | 91 | //$this->cleanupMailingTest(); |
07c09ae4 | 92 | parent::tearDown(); |
07c09ae4 EM |
93 | } |
94 | ||
d667a9ba | 95 | public function testBasic() { |
07c09ae4 | 96 | $this->createContactsInGroup(10, $this->_groupID); |
9099cab3 | 97 | Civi::settings()->add([ |
d667a9ba | 98 | 'mailerBatchLimit' => 2, |
9099cab3 | 99 | ]); |
07c09ae4 | 100 | $this->callAPISuccess('mailing', 'create', $this->_params); |
9099cab3 CW |
101 | $this->_mut->assertRecipients([]); |
102 | $this->callAPISuccess('job', 'process_mailing', []); | |
07c09ae4 | 103 | $this->_mut->assertRecipients($this->getRecipients(1, 2)); |
4aa8f804 JP |
104 | } |
105 | ||
acaec976 SL |
106 | /** |
107 | * Test what happens when a contact is set to decesaed | |
108 | */ | |
109 | public function testDecesasedRecepient() { | |
110 | $contactID = $this->individualCreate(['first_name' => 'test dead recipeint', 'email' => 'mailtestdead@civicrm.org']); | |
111 | $this->callAPISuccess('group_contact', 'create', [ | |
112 | 'contact_id' => $contactID, | |
113 | 'group_id' => $this->_groupID, | |
114 | 'status' => 'Added', | |
115 | ]); | |
116 | $this->createContactsInGroup(2, $this->_groupID); | |
117 | Civi::settings()->add([ | |
118 | 'mailerBatchLimit' => 2, | |
119 | ]); | |
120 | $mailing = $this->callAPISuccess('mailing', 'create', $this->_params); | |
121 | $this->assertEquals(3, $this->callAPISuccess('MailingRecipients', 'get', ['mailing_id' => $mailing['id']])['count']); | |
122 | $this->_mut->assertRecipients([]); | |
123 | $this->callAPISuccess('Contact', 'create', ['id' => $contactID, 'is_deceased' => 1, 'contact_type' => 'Individual']); | |
124 | $this->callAPISuccess('job', 'process_mailing', []); | |
125 | // Check that the deceased contact is not found in the mailing. | |
126 | $this->_mut->assertRecipients($this->getRecipients(1, 2)); | |
127 | ||
128 | } | |
129 | ||
4aa8f804 JP |
130 | /** |
131 | * Test pause and resume on Mailing. | |
132 | */ | |
133 | public function testPauseAndResumeMailing() { | |
134 | $this->createContactsInGroup(10, $this->_groupID); | |
9099cab3 | 135 | Civi::settings()->add([ |
4aa8f804 | 136 | 'mailerBatchLimit' => 2, |
9099cab3 | 137 | ]); |
67d4ed51 | 138 | $this->_mut->clearMessages(); |
4aa8f804 JP |
139 | //Create a test mailing and check if the status is set to Scheduled. |
140 | $result = $this->callAPISuccess('mailing', 'create', $this->_params); | |
9099cab3 | 141 | $jobs = $this->callAPISuccess('mailing_job', 'get', ['mailing_id' => $result['id']]); |
4aa8f804 JP |
142 | $this->assertEquals('Scheduled', $jobs['values'][$jobs['id']]['status']); |
143 | ||
67d4ed51 | 144 | //Pause the mailing. |
4aa8f804 | 145 | CRM_Mailing_BAO_MailingJob::pause($result['id']); |
9099cab3 | 146 | $jobs = $this->callAPISuccess('mailing_job', 'get', ['mailing_id' => $result['id']]); |
4aa8f804 JP |
147 | $this->assertEquals('Paused', $jobs['values'][$jobs['id']]['status']); |
148 | ||
149 | //Verify if Paused mailing isn't considered in process_mailing job. | |
9099cab3 | 150 | $this->callAPISuccess('job', 'process_mailing', []); |
67d4ed51 JP |
151 | //Check if mail log is empty. |
152 | $this->_mut->assertMailLogEmpty(); | |
9099cab3 | 153 | $jobs = $this->callAPISuccess('mailing_job', 'get', ['mailing_id' => $result['id']]); |
4aa8f804 JP |
154 | $this->assertEquals('Paused', $jobs['values'][$jobs['id']]['status']); |
155 | ||
156 | //Resume should set the status back to Scheduled. | |
157 | CRM_Mailing_BAO_MailingJob::resume($result['id']); | |
9099cab3 | 158 | $jobs = $this->callAPISuccess('mailing_job', 'get', ['mailing_id' => $result['id']]); |
4aa8f804 | 159 | $this->assertEquals('Scheduled', $jobs['values'][$jobs['id']]['status']); |
67d4ed51 JP |
160 | |
161 | //Execute the job and it should send the mailing to the recipients now. | |
9099cab3 | 162 | $this->callAPISuccess('job', 'process_mailing', []); |
67d4ed51 | 163 | $this->_mut->assertRecipients($this->getRecipients(1, 2)); |
00cc2e4b SL |
164 | // Ensure that loading the report produces no errors. |
165 | $report = CRM_Mailing_BAO_Mailing::report($result['id']); | |
166 | // dev/mailing#56 dev/mailing#57 Ensure that for completed mailings the jobs array is not empty. | |
167 | $this->assertTrue(!empty($report['jobs'])); | |
168 | // Ensure that mailing name is correctly stored in the report. | |
169 | $this->assertEquals('mailing name', $report['mailing']['name']); | |
07c09ae4 EM |
170 | } |
171 | ||
f008885c E |
172 | /** |
173 | * Test mail when in non-production environment. | |
174 | * | |
175 | */ | |
176 | public function testMailNonProductionRun() { | |
177 | // Test in non-production mode. | |
9099cab3 | 178 | $params = [ |
f008885c | 179 | 'environment' => 'Staging', |
9099cab3 | 180 | ]; |
f008885c | 181 | $this->callAPISuccess('Setting', 'create', $params); |
288e5f75 JP |
182 | //Assert if outbound mail is disabled. |
183 | $mailingBackend = Civi::settings()->get('mailing_backend'); | |
184 | $this->assertEquals($mailingBackend['outBound_option'], CRM_Mailing_Config::OUTBOUND_OPTION_DISABLED); | |
185 | ||
f008885c | 186 | $this->createContactsInGroup(10, $this->_groupID); |
9099cab3 | 187 | Civi::settings()->add([ |
f008885c | 188 | 'mailerBatchLimit' => 2, |
9099cab3 | 189 | ]); |
f008885c | 190 | $this->callAPISuccess('mailing', 'create', $this->_params); |
9099cab3 | 191 | $this->_mut->assertRecipients([]); |
3241b690 | 192 | $result = $this->callAPIFailure('job', 'process_mailing', []); |
193 | $this->assertEquals($result['error_message'], "Job has not been executed as it is a Staging (non-production) environment."); | |
f008885c E |
194 | |
195 | // Test with runInNonProductionEnvironment param. | |
9099cab3 | 196 | $this->callAPISuccess('job', 'process_mailing', ['runInNonProductionEnvironment' => TRUE]); |
f008885c E |
197 | $this->_mut->assertRecipients($this->getRecipients(1, 2)); |
198 | ||
9099cab3 | 199 | $jobId = $this->callAPISuccessGetValue('Job', [ |
288e5f75 JP |
200 | 'return' => "id", |
201 | 'api_action' => "group_rebuild", | |
9099cab3 CW |
202 | ]); |
203 | $this->callAPISuccess('Job', 'create', [ | |
288e5f75 JP |
204 | 'id' => $jobId, |
205 | 'parameters' => "runInNonProductionEnvironment=TRUE", | |
9099cab3 | 206 | ]); |
288e5f75 JP |
207 | $jobManager = new CRM_Core_JobManager(); |
208 | $jobManager->executeJobById($jobId); | |
209 | ||
210 | //Assert if outbound mail is still disabled. | |
211 | $mailingBackend = Civi::settings()->get('mailing_backend'); | |
212 | $this->assertEquals($mailingBackend['outBound_option'], CRM_Mailing_Config::OUTBOUND_OPTION_DISABLED); | |
213 | ||
f008885c | 214 | // Test in production mode. |
9099cab3 | 215 | $params = [ |
f008885c | 216 | 'environment' => 'Production', |
9099cab3 | 217 | ]; |
f008885c | 218 | $this->callAPISuccess('Setting', 'create', $params); |
9099cab3 | 219 | $this->callAPISuccess('job', 'process_mailing', []); |
f008885c E |
220 | $this->_mut->assertRecipients($this->getRecipients(1, 2)); |
221 | } | |
222 | ||
d667a9ba | 223 | public function concurrencyExamples() { |
9099cab3 | 224 | $es = []; |
d667a9ba TO |
225 | |
226 | // Launch 3 workers, but mailerJobsMax limits us to 1 worker. | |
9099cab3 CW |
227 | $es[0] = [ |
228 | [ | |
d667a9ba TO |
229 | 'recipients' => 20, |
230 | 'workers' => 3, | |
a2341a99 TO |
231 | // FIXME: lockHold is unrealistic/unrepresentative. In reality, this situation fails because |
232 | // the data.* locks trample the worker.* locks. However, setting lockHold allows us to | |
233 | // approximate the behavior of what would happen *if* the lock-implementation didn't suffer | |
234 | // trampling effects. | |
d667a9ba TO |
235 | 'lockHold' => 10, |
236 | 'mailerBatchLimit' => 4, | |
237 | 'mailerJobsMax' => 1, | |
9099cab3 CW |
238 | ], |
239 | [ | |
39b9dbb3 | 240 | // 2 jobs which produce 0 messages |
39b959db | 241 | 0 => 2, |
39b9dbb3 | 242 | // 1 job which produces 4 messages |
39b959db | 243 | 4 => 1, |
9099cab3 | 244 | ], |
d667a9ba | 245 | 4, |
9099cab3 | 246 | ]; |
d667a9ba TO |
247 | |
248 | // Launch 3 workers, but mailerJobsMax limits us to 2 workers. | |
9099cab3 | 249 | $es[1] = [ |
39b959db | 250 | // Settings. |
9099cab3 | 251 | [ |
d667a9ba TO |
252 | 'recipients' => 20, |
253 | 'workers' => 3, | |
a2341a99 TO |
254 | // FIXME: lockHold is unrealistic/unrepresentative. In reality, this situation fails because |
255 | // the data.* locks trample the worker.* locks. However, setting lockHold allows us to | |
256 | // approximate the behavior of what would happen *if* the lock-implementation didn't suffer | |
257 | // trampling effects. | |
d667a9ba TO |
258 | 'lockHold' => 10, |
259 | 'mailerBatchLimit' => 5, | |
260 | 'mailerJobsMax' => 2, | |
9099cab3 | 261 | ], |
39b959db | 262 | // Tallies. |
9099cab3 | 263 | [ |
39b959db SL |
264 | // 1 job which produce 0 messages |
265 | 0 => 1, | |
266 | // 2 jobs which produce 5 messages | |
267 | 5 => 2, | |
9099cab3 | 268 | ], |
39b959db SL |
269 | // Total sent. |
270 | 10, | |
9099cab3 | 271 | ]; |
d667a9ba TO |
272 | |
273 | // Launch 3 workers and saturate them (mailerJobsMax=3) | |
9099cab3 | 274 | $es[2] = [ |
39b959db | 275 | // Settings. |
9099cab3 | 276 | [ |
d667a9ba TO |
277 | 'recipients' => 20, |
278 | 'workers' => 3, | |
d667a9ba TO |
279 | 'mailerBatchLimit' => 6, |
280 | 'mailerJobsMax' => 3, | |
9099cab3 | 281 | ], |
39b959db | 282 | // Tallies. |
9099cab3 | 283 | [ |
39b959db SL |
284 | // 3 jobs which produce 6 messages |
285 | 6 => 3, | |
9099cab3 | 286 | ], |
39b959db SL |
287 | // Total sent. |
288 | 18, | |
9099cab3 | 289 | ]; |
d667a9ba TO |
290 | |
291 | // Launch 4 workers and saturate them (mailerJobsMax=0) | |
9099cab3 | 292 | $es[3] = [ |
39b959db | 293 | // Settings. |
9099cab3 | 294 | [ |
d667a9ba TO |
295 | 'recipients' => 20, |
296 | 'workers' => 4, | |
d667a9ba TO |
297 | 'mailerBatchLimit' => 6, |
298 | 'mailerJobsMax' => 0, | |
9099cab3 | 299 | ], |
39b959db | 300 | // Tallies. |
9099cab3 | 301 | [ |
39b959db SL |
302 | // 3 jobs which produce 6 messages |
303 | 6 => 3, | |
304 | // 1 job which produces 2 messages | |
305 | 2 => 1, | |
9099cab3 | 306 | ], |
39b959db SL |
307 | // Total sent. |
308 | 20, | |
9099cab3 | 309 | ]; |
d667a9ba TO |
310 | |
311 | // Launch 1 worker, 3 times in a row. Deliver everything. | |
9099cab3 | 312 | $es[4] = [ |
39b959db | 313 | // Settings. |
9099cab3 | 314 | [ |
d667a9ba TO |
315 | 'recipients' => 10, |
316 | 'workers' => 1, | |
317 | 'iterations' => 3, | |
318 | 'mailerBatchLimit' => 7, | |
9099cab3 | 319 | ], |
39b959db | 320 | // Tallies. |
9099cab3 | 321 | [ |
39b959db SL |
322 | // 1 job which produces 7 messages |
323 | 7 => 1, | |
324 | // 1 job which produces 3 messages | |
325 | 3 => 1, | |
326 | // 1 job which produces 0 messages | |
327 | 0 => 1, | |
9099cab3 | 328 | ], |
39b959db SL |
329 | // Total sent. |
330 | 10, | |
9099cab3 | 331 | ]; |
d667a9ba TO |
332 | |
333 | // Launch 2 worker, 3 times in a row. Deliver everything. | |
9099cab3 | 334 | $es[5] = [ |
39b959db | 335 | // Settings. |
9099cab3 | 336 | [ |
d667a9ba TO |
337 | 'recipients' => 10, |
338 | 'workers' => 2, | |
339 | 'iterations' => 3, | |
340 | 'mailerBatchLimit' => 3, | |
9099cab3 | 341 | ], |
39b959db | 342 | // Tallies. |
9099cab3 | 343 | [ |
39b959db SL |
344 | // 3 jobs which produce 3 messages |
345 | 3 => 3, | |
346 | // 1 job which produces 1 messages | |
347 | 1 => 1, | |
348 | // 2 jobs which produce 0 messages | |
349 | 0 => 2, | |
9099cab3 | 350 | ], |
39b959db SL |
351 | // Total sent. |
352 | 10, | |
9099cab3 | 353 | ]; |
d667a9ba | 354 | |
502eefb0 | 355 | // For two mailings, launch 1 worker, 5 times in a row. Deliver everything. |
9099cab3 | 356 | $es[6] = [ |
39b959db | 357 | // Settings. |
9099cab3 | 358 | [ |
502eefb0 TO |
359 | 'mailings' => 2, |
360 | 'recipients' => 10, | |
361 | 'workers' => 1, | |
362 | 'iterations' => 5, | |
363 | 'mailerBatchLimit' => 6, | |
9099cab3 | 364 | ], |
39b959db | 365 | // Tallies. |
9099cab3 | 366 | [ |
502eefb0 | 367 | // x6 => x4+x2 => x6 => x2 => x0 |
39b959db SL |
368 | // 3 jobs which produce 6 messages |
369 | 6 => 3, | |
370 | // 1 job which produces 2 messages | |
371 | 2 => 1, | |
372 | // 1 job which produces 0 messages | |
373 | 0 => 1, | |
9099cab3 | 374 | ], |
39b959db SL |
375 | // Total sent. |
376 | 20, | |
9099cab3 | 377 | ]; |
502eefb0 | 378 | |
d667a9ba TO |
379 | return $es; |
380 | } | |
381 | ||
382 | /** | |
383 | * Setup various mail configuration options (eg $mailerBatchLimit, | |
384 | * $mailerJobMax) and spawn multiple worker threads ($workers). | |
385 | * Allow the threads to complete. (Optionally, repeat the above | |
386 | * process.) Finally, check to see if the right number of | |
387 | * jobs delivered the right number of messages. | |
388 | * | |
389 | * @param array $settings | |
390 | * An array of settings (eg mailerBatchLimit, workers). See comments | |
391 | * for $this->defaultSettings. | |
392 | * @param array $expectedTallies | |
393 | * A listing of the number cron-runs keyed by their size. | |
394 | * For example, array(10=>2) means that there 2 cron-runs | |
395 | * which delivered 10 messages each. | |
396 | * @param int $expectedTotal | |
397 | * The total number of contacts for whom messages should have | |
398 | * been sent. | |
399 | * @dataProvider concurrencyExamples | |
400 | */ | |
401 | public function testConcurrency($settings, $expectedTallies, $expectedTotal) { | |
402 | $settings = array_merge($this->defaultSettings, $settings); | |
403 | ||
404 | $this->createContactsInGroup($settings['recipients'], $this->_groupID); | |
9099cab3 | 405 | Civi::settings()->add(CRM_Utils_Array::subset($settings, [ |
d667a9ba TO |
406 | 'mailerBatchLimit', |
407 | 'mailerJobsMax', | |
408 | 'mailThrottleTime', | |
9099cab3 | 409 | ])); |
d667a9ba | 410 | |
502eefb0 TO |
411 | for ($i = 0; $i < $settings['mailings']; $i++) { |
412 | $this->callAPISuccess('mailing', 'create', $this->_params); | |
413 | } | |
d667a9ba | 414 | |
9099cab3 | 415 | $this->_mut->assertRecipients([]); |
d667a9ba | 416 | |
9099cab3 | 417 | $allApiResults = []; |
d667a9ba TO |
418 | for ($iterationId = 0; $iterationId < $settings['iterations']; $iterationId++) { |
419 | $apiCalls = $this->createExternalAPI(); | |
9099cab3 | 420 | $apiCalls->addEnv(['CIVICRM_CRON_HOLD' => $settings['lockHold']]); |
d667a9ba | 421 | for ($workerId = 0; $workerId < $settings['workers']; $workerId++) { |
9099cab3 | 422 | $apiCalls->addCall('job', 'process_mailing', []); |
d667a9ba TO |
423 | } |
424 | $apiCalls->start(); | |
425 | $this->assertEquals($settings['workers'], $apiCalls->getRunningCount()); | |
426 | ||
427 | $apiCalls->wait(); | |
428 | $allApiResults = array_merge($allApiResults, $apiCalls->getResults()); | |
429 | } | |
430 | ||
431 | $actualTallies = $this->tallyApiResults($allApiResults); | |
9099cab3 | 432 | $this->assertEquals($expectedTallies, $actualTallies, 'API tallies should match.' . print_r([ |
39b959db SL |
433 | 'expectedTallies' => $expectedTallies, |
434 | 'actualTallies' => $actualTallies, | |
435 | 'apiResults' => $allApiResults, | |
9099cab3 | 436 | ], TRUE)); |
502eefb0 | 437 | $this->_mut->assertRecipients($this->getRecipients(1, $expectedTotal / $settings['mailings'], 'nul.example.com', $settings['mailings'])); |
d667a9ba TO |
438 | $this->assertEquals(0, $apiCalls->getRunningCount()); |
439 | } | |
440 | ||
07c09ae4 | 441 | /** |
54957108 | 442 | * Create contacts in group. |
443 | * | |
e16033b4 TO |
444 | * @param int $count |
445 | * @param int $groupID | |
54957108 | 446 | * @param string $domain |
07c09ae4 | 447 | */ |
d667a9ba | 448 | public function createContactsInGroup($count, $groupID, $domain = 'nul.example.com') { |
481a74f4 | 449 | for ($i = 1; $i <= $count; $i++) { |
9099cab3 CW |
450 | $contactID = $this->individualCreate(['first_name' => $count, 'email' => 'mail' . $i . '@' . $domain]); |
451 | $this->callAPISuccess('group_contact', 'create', [ | |
d667a9ba TO |
452 | 'contact_id' => $contactID, |
453 | 'group_id' => $groupID, | |
454 | 'status' => 'Added', | |
9099cab3 | 455 | ]); |
07c09ae4 EM |
456 | } |
457 | } | |
458 | ||
459 | /** | |
d667a9ba TO |
460 | * Construct the list of email addresses for $count recipients. |
461 | * | |
e16033b4 TO |
462 | * @param int $start |
463 | * @param int $count | |
502eefb0 TO |
464 | * @param string $domain |
465 | * @param int $mailings | |
07c09ae4 EM |
466 | * |
467 | * @return array | |
468 | */ | |
502eefb0 | 469 | public function getRecipients($start, $count, $domain = 'nul.example.com', $mailings = 1) { |
9099cab3 | 470 | $recipients = []; |
502eefb0 TO |
471 | for ($m = 0; $m < $mailings; $m++) { |
472 | for ($i = $start; $i < ($start + $count); $i++) { | |
473 | $recipients[][0] = 'mail' . $i . '@' . $domain; | |
474 | } | |
07c09ae4 EM |
475 | } |
476 | return $recipients; | |
477 | } | |
96025800 | 478 | |
d667a9ba | 479 | protected function cleanupMailingTest() { |
9099cab3 | 480 | $this->quickCleanup([ |
d667a9ba TO |
481 | 'civicrm_mailing', |
482 | 'civicrm_mailing_job', | |
483 | 'civicrm_mailing_spool', | |
484 | 'civicrm_mailing_group', | |
485 | 'civicrm_mailing_recipients', | |
486 | 'civicrm_mailing_event_queue', | |
487 | 'civicrm_mailing_event_bounce', | |
488 | 'civicrm_mailing_event_delivered', | |
489 | 'civicrm_group', | |
490 | 'civicrm_group_contact', | |
491 | 'civicrm_contact', | |
9099cab3 | 492 | ]); |
d667a9ba TO |
493 | } |
494 | ||
495 | /** | |
496 | * Categorize results based on (a) whether they succeeded | |
497 | * and (b) the number of messages sent. | |
498 | * | |
499 | * @param array $apiResults | |
500 | * @return array | |
501 | * One key 'error' for all failures. | |
502 | * A separate key for each distinct quantity. | |
503 | */ | |
504 | protected function tallyApiResults($apiResults) { | |
9099cab3 | 505 | $ret = []; |
d667a9ba TO |
506 | foreach ($apiResults as $apiResult) { |
507 | $key = !empty($apiResult['is_error']) ? 'error' : $apiResult['values']['processed']; | |
508 | $ret[$key] = !empty($ret[$key]) ? 1 + $ret[$key] : 1; | |
509 | } | |
510 | return $ret; | |
511 | } | |
512 | ||
07c09ae4 | 513 | } |