CRM-13244 - CRM_Core_BAO_ActionSchedule - Simplify `sendMailing()`
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / ActionScheduleTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
81621fee 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28
29require_once 'CiviTest/CiviUnitTestCase.php';
e9479dcf
EM
30
31/**
32 * Class CRM_Core_BAO_ActionScheduleTest
33 */
6a488035 34class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
63e9c3fd 35
6a488035 36 /**
f8c3594b 37 * @var CiviMailUtils
6a488035 38 */
567b2076 39 public $mut;
cee19268 40
00be9182 41 public function setUp() {
6a488035
TO
42 parent::setUp();
43
44 require_once 'CiviTest/CiviMailUtils.php';
6c6e6187 45 $this->mut = new CiviMailUtils($this, TRUE);
6a488035 46
57507ae6 47 $this->fixtures['rolling_membership'] = array(
6a488035
TO
48 'membership_type_id' => array(
49 'period_type' => 'rolling',
50 'duration_unit' => 'month',
51 'duration_interval' => '3',
52 'is_active' => 1,
53 ),
54 'join_date' => '20120315',
55 'start_date' => '20120315',
56 'end_date' => '20120615',
b29be8c2 57 'is_override' => 0,
6a488035 58 );
4b1efa1d 59
63e9c3fd 60 $this->fixtures['rolling_membership_past'] = array(
4b1efa1d 61 'membership_type_id' => array(
62 'period_type' => 'rolling',
63 'duration_unit' => 'month',
64 'duration_interval' => '3',
65 'is_active' => 1,
66 ),
67 'join_date' => '20100310',
68 'start_date' => '20100310',
69 'end_date' => '20100610',
70 'is_override' => 'NULL',
71 );
fe265b4e 72
db7de9c1 73 $this->fixtures['phonecall'] = array(
6a488035
TO
74 'status_id' => 1,
75 'activity_type_id' => 2,
76 'activity_date_time' => '20120615100000',
77 'is_current_revision' => 1,
78 'is_deleted' => 0,
79 );
db7de9c1 80 $this->fixtures['contact'] = array(
b29be8c2 81 'is_deceased' => 0,
6a488035
TO
82 'contact_type' => 'Individual',
83 'email' => 'test-member@example.com',
43ceab3f 84 'gender_id' => 'Female',
6a488035 85 );
db7de9c1 86 $this->fixtures['contact_birthdate'] = array(
43030baf
AH
87 'is_deceased' => 0,
88 'contact_type' => 'Individual',
89 'email' => 'test-bday@example.com',
90 'birth_date' => '20050707',
91 );
db7de9c1 92 $this->fixtures['sched_activity_1day'] = array(
6a488035
TO
93 'name' => 'One_Day_Phone_Call_Notice',
94 'title' => 'One Day Phone Call Notice',
84a3e359 95 'limit_to' => '1',
6a488035
TO
96 'absolute_date' => NULL,
97 'body_html' => '<p>1-Day (non-repeating)</p>',
98 'body_text' => '1-Day (non-repeating)',
99 'end_action' => NULL,
100 'end_date' => NULL,
101 'end_frequency_interval' => NULL,
102 'end_frequency_unit' => NULL,
103 'entity_status' => '1',
104 'entity_value' => '2',
105 'group_id' => NULL,
106 'is_active' => '1',
107 'is_repeat' => '0',
108 'mapping_id' => '1',
109 'msg_template_id' => NULL,
110 'recipient' => '2',
111 'recipient_listing' => NULL,
112 'recipient_manual' => NULL,
113 'record_activity' => NULL,
114 'repetition_frequency_interval' => NULL,
115 'repetition_frequency_unit' => NULL,
116 'start_action_condition' => 'before',
117 'start_action_date' => 'activity_date_time',
118 'start_action_offset' => '1',
119 'start_action_unit' => 'day',
f8c3594b 120 'subject' => '1-Day (non-repeating) (about {activity.activity_type})',
6a488035
TO
121 );
122 $this->fixtures['sched_activity_1day_r'] = array(
123 'name' => 'One_Day_Phone_Call_Notice_R',
124 'title' => 'One Day Phone Call Notice R',
84a3e359 125 'limit_to' => 1,
6a488035
TO
126 'absolute_date' => NULL,
127 'body_html' => '<p>1-Day (repeating)</p>',
128 'body_text' => '1-Day (repeating)',
129 'end_action' => 'after',
130 'end_date' => 'activity_date_time',
131 'end_frequency_interval' => '2',
132 'end_frequency_unit' => 'day',
133 'entity_status' => '1',
134 'entity_value' => '2',
135 'group_id' => NULL,
136 'is_active' => '1',
137 'is_repeat' => '1',
138 'mapping_id' => '1',
139 'msg_template_id' => NULL,
140 'recipient' => '2',
141 'recipient_listing' => NULL,
142 'recipient_manual' => NULL,
143 'record_activity' => NULL,
144 'repetition_frequency_interval' => '6',
145 'repetition_frequency_unit' => 'hour',
146 'start_action_condition' => 'before',
147 'start_action_date' => 'activity_date_time',
148 'start_action_offset' => '1',
149 'start_action_unit' => 'day',
f8c3594b 150 'subject' => '1-Day (repeating) (about {activity.activity_type})',
6a488035 151 );
567b2076 152 $this->fixtures['sched_membership_join_2week'] = array(
6a488035
TO
153 'name' => 'sched_membership_join_2week',
154 'title' => 'sched_membership_join_2week',
155 'absolute_date' => '',
156 'body_html' => '<p>body sched_membership_join_2week</p>',
157 'body_text' => 'body sched_membership_join_2week',
158 'end_action' => '',
159 'end_date' => '',
160 'end_frequency_interval' => '',
161 'end_frequency_unit' => '',
162 'entity_status' => '',
163 'entity_value' => '',
164 'group_id' => '',
165 'is_active' => 1,
166 'is_repeat' => '0',
167 'mapping_id' => 4,
168 'msg_template_id' => '',
169 'recipient' => '',
170 'recipient_listing' => '',
171 'recipient_manual' => '',
172 'record_activity' => 1,
173 'repetition_frequency_interval' => '',
174 'repetition_frequency_unit' => '',
175 'start_action_condition' => 'after',
176 'start_action_date' => 'membership_join_date',
177 'start_action_offset' => '2',
178 'start_action_unit' => 'week',
f8c3594b 179 'subject' => 'subject sched_membership_join_2week (joined {membership.join_date})',
6a488035 180 );
567b2076 181 $this->fixtures['sched_membership_end_2week'] = array(
6a488035
TO
182 'name' => 'sched_membership_end_2week',
183 'title' => 'sched_membership_end_2week',
184 'absolute_date' => '',
185 'body_html' => '<p>body sched_membership_end_2week</p>',
186 'body_text' => 'body sched_membership_end_2week',
187 'end_action' => '',
188 'end_date' => '',
189 'end_frequency_interval' => '',
190 'end_frequency_unit' => '',
191 'entity_status' => '',
192 'entity_value' => '',
193 'group_id' => '',
194 'is_active' => 1,
195 'is_repeat' => '0',
196 'mapping_id' => 4,
197 'msg_template_id' => '',
198 'recipient' => '',
199 'recipient_listing' => '',
200 'recipient_manual' => '',
201 'record_activity' => 1,
202 'repetition_frequency_interval' => '',
203 'repetition_frequency_unit' => '',
204 'start_action_condition' => 'before',
205 'start_action_date' => 'membership_end_date',
206 'start_action_offset' => '2',
207 'start_action_unit' => 'week',
208 'subject' => 'subject sched_membership_end_2week',
209 );
cbcb7579 210 $this->fixtures['sched_on_membership_end_date'] = array(
d2868251 211 'name' => 'sched_on_membership_end_date',
212 'title' => 'sched_on_membership_end_date',
213 'body_html' => '<p>Your membership expired today</p>',
214 'body_text' => 'Your membership expired today',
215 'is_active' => 1,
216 'mapping_id' => 4,
217 'record_activity' => 1,
218 'start_action_condition' => 'after',
219 'start_action_date' => 'membership_end_date',
220 'start_action_offset' => '0',
221 'start_action_unit' => 'hour',
222 'subject' => 'subject send reminder on membership_end_date',
223 );
cbcb7579 224 $this->fixtures['sched_after_1day_membership_end_date'] = array(
d2868251 225 'name' => 'sched_after_1day_membership_end_date',
226 'title' => 'sched_after_1day_membership_end_date',
227 'body_html' => '<p>Your membership expired yesterday</p>',
228 'body_text' => 'Your membership expired yesterday',
229 'is_active' => 1,
230 'mapping_id' => 4,
231 'record_activity' => 1,
232 'start_action_condition' => 'after',
233 'start_action_date' => 'membership_end_date',
234 'start_action_offset' => '1',
235 'start_action_unit' => 'day',
236 'subject' => 'subject send reminder on membership_end_date',
237 );
4b1efa1d 238
567b2076 239 $this->fixtures['sched_membership_end_2month'] = array(
4b1efa1d 240 'name' => 'sched_membership_end_2month',
241 'title' => 'sched_membership_end_2month',
242 'absolute_date' => '',
243 'body_html' => '<p>body sched_membership_end_2month</p>',
244 'body_text' => 'body sched_membership_end_2month',
245 'end_action' => '',
246 'end_date' => '',
247 'end_frequency_interval' => '',
248 'end_frequency_unit' => '',
249 'entity_status' => '',
250 'entity_value' => '',
251 'group_id' => '',
252 'is_active' => 1,
253 'is_repeat' => '0',
254 'mapping_id' => 4,
255 'msg_template_id' => '',
256 'recipient' => '',
257 'recipient_listing' => '',
258 'recipient_manual' => '',
259 'record_activity' => 1,
260 'repetition_frequency_interval' => '',
261 'repetition_frequency_unit' => '',
262 'start_action_condition' => 'after',
263 'start_action_date' => 'membership_end_date',
264 'start_action_offset' => '2',
265 'start_action_unit' => 'month',
266 'subject' => 'subject sched_membership_end_2month',
267 );
268
567b2076 269 $this->fixtures['sched_contact_bday_yesterday'] = array(
43030baf
AH
270 'name' => 'sched_contact_bday_yesterday',
271 'title' => 'sched_contact_bday_yesterday',
272 'absolute_date' => '',
273 'body_html' => '<p>you look like you were born yesterday!</p>',
274 'body_text' => 'you look like you were born yesterday!',
275 'end_action' => '',
276 'end_date' => '',
277 'end_frequency_interval' => '',
278 'end_frequency_unit' => '',
279 'entity_status' => 1,
280 'entity_value' => 'birth_date',
281 'group_id' => '',
282 'is_active' => 1,
283 'is_repeat' => '0',
284 'mapping_id' => 6,
285 'msg_template_id' => '',
286 'recipient' => '',
287 'recipient_listing' => '',
288 'recipient_manual' => '',
289 'record_activity' => 1,
290 'repetition_frequency_interval' => '',
291 'repetition_frequency_unit' => '',
292 'start_action_condition' => 'after',
293 'start_action_date' => 'date_field',
294 'start_action_offset' => '1',
295 'start_action_unit' => 'day',
296 'subject' => 'subject sched_contact_bday_yesterday',
297 );
298
567b2076 299 $this->fixtures['sched_contact_bday_anniv'] = array(
43030baf
AH
300 'name' => 'sched_contact_bday_anniv',
301 'title' => 'sched_contact_bday_anniv',
302 'absolute_date' => '',
303 'body_html' => '<p>happy birthday!</p>',
304 'body_text' => 'happy birthday!',
305 'end_action' => '',
306 'end_date' => '',
307 'end_frequency_interval' => '',
308 'end_frequency_unit' => '',
309 'entity_status' => 2,
310 'entity_value' => 'birth_date',
311 'group_id' => '',
312 'is_active' => 1,
313 'is_repeat' => '0',
314 'mapping_id' => 6,
315 'msg_template_id' => '',
316 'recipient' => '',
317 'recipient_listing' => '',
318 'recipient_manual' => '',
319 'record_activity' => 1,
320 'repetition_frequency_interval' => '',
321 'repetition_frequency_unit' => '',
322 'start_action_condition' => 'before',
323 'start_action_date' => 'date_field',
324 'start_action_offset' => '1',
325 'start_action_unit' => 'day',
326 'subject' => 'subject sched_contact_bday_anniv',
327 );
328
567b2076 329 $this->fixtures['sched_contact_grad_tomorrow'] = array(
43030baf
AH
330 'name' => 'sched_contact_grad_tomorrow',
331 'title' => 'sched_contact_grad_tomorrow',
332 'absolute_date' => '',
333 'body_html' => '<p>congratulations on your graduation!</p>',
334 'body_text' => 'congratulations on your graduation!',
335 'end_action' => '',
336 'end_date' => '',
337 'end_frequency_interval' => '',
338 'end_frequency_unit' => '',
339 'entity_status' => 1,
340 'group_id' => '',
341 'is_active' => 1,
342 'is_repeat' => '0',
343 'mapping_id' => 6,
344 'msg_template_id' => '',
345 'recipient' => '',
346 'recipient_listing' => '',
347 'recipient_manual' => '',
348 'record_activity' => 1,
349 'repetition_frequency_interval' => '',
350 'repetition_frequency_unit' => '',
351 'start_action_condition' => 'before',
352 'start_action_date' => 'date_field',
353 'start_action_offset' => '1',
354 'start_action_unit' => 'day',
355 'subject' => 'subject sched_contact_grad_tomorrow',
356 );
357
567b2076 358 $this->fixtures['sched_contact_grad_anniv'] = array(
43030baf
AH
359 'name' => 'sched_contact_grad_anniv',
360 'title' => 'sched_contact_grad_anniv',
361 'absolute_date' => '',
362 'body_html' => '<p>dear alum, please send us money.</p>',
363 'body_text' => 'dear alum, please send us money.',
364 'end_action' => '',
365 'end_date' => '',
366 'end_frequency_interval' => '',
367 'end_frequency_unit' => '',
368 'entity_status' => 2,
369 'group_id' => '',
370 'is_active' => 1,
371 'is_repeat' => '0',
372 'mapping_id' => 6,
373 'msg_template_id' => '',
374 'recipient' => '',
375 'recipient_listing' => '',
376 'recipient_manual' => '',
377 'record_activity' => 1,
378 'repetition_frequency_interval' => '',
379 'repetition_frequency_unit' => '',
380 'start_action_condition' => 'after',
381 'start_action_date' => 'date_field',
382 'start_action_offset' => '1',
383 'start_action_unit' => 'week',
384 'subject' => 'subject sched_contact_grad_anniv',
385 );
4aff0253
AH
386
387 $this->fixtures['sched_contact_created_yesterday'] = array(
388 'name' => 'sched_contact_created_yesterday',
389 'title' => 'sched_contact_created_yesterday',
390 'absolute_date' => '',
391 'body_html' => '<p>Your contact was created yesterday</p>',
392 'body_text' => 'Your contact was created yesterday!',
393 'end_action' => '',
394 'end_date' => '',
395 'end_frequency_interval' => '',
396 'end_frequency_unit' => '',
397 'entity_status' => 1,
398 'entity_value' => 'created_date',
399 'group_id' => '',
400 'is_active' => 1,
401 'is_repeat' => '0',
402 'mapping_id' => 6,
403 'msg_template_id' => '',
404 'recipient' => '',
405 'recipient_listing' => '',
406 'recipient_manual' => '',
407 'record_activity' => 1,
408 'repetition_frequency_interval' => '',
409 'repetition_frequency_unit' => '',
410 'start_action_condition' => 'after',
411 'start_action_date' => 'date_field',
412 'start_action_offset' => '1',
413 'start_action_unit' => 'day',
414 'subject' => 'subject sched_contact_created_yesterday',
415 );
416
417 $this->fixtures['sched_contact_mod_anniv'] = array(
418 'name' => 'sched_contact_mod_anniv',
419 'title' => 'sched_contact_mod_anniv',
420 'absolute_date' => '',
421 'body_html' => '<p>You last updated your data last year</p>',
422 'body_text' => 'Go update your stuff!',
423 'end_action' => '',
424 'end_date' => '',
425 'end_frequency_interval' => '',
426 'end_frequency_unit' => '',
427 'entity_status' => 2,
428 'entity_value' => 'modified_date',
429 'group_id' => '',
430 'is_active' => 1,
431 'is_repeat' => '0',
432 'mapping_id' => 6,
433 'msg_template_id' => '',
434 'recipient' => '',
435 'recipient_listing' => '',
436 'recipient_manual' => '',
437 'record_activity' => 1,
438 'repetition_frequency_interval' => '',
439 'repetition_frequency_unit' => '',
440 'start_action_condition' => 'before',
441 'start_action_date' => 'date_field',
442 'start_action_offset' => '1',
443 'start_action_unit' => 'day',
444 'subject' => 'subject sched_contact_mod_anniv',
445 );
446
567b2076 447 $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'] = array(
861d11c4
DG
448 'name' => 'sched_membership_end_2month',
449 'title' => 'sched_membership_end_2month',
450 'absolute_date' => '',
451 'body_html' => '<p>body sched_membership_end_2month</p>',
452 'body_text' => 'body sched_membership_end_2month',
453 'end_action' => '',
5c4d6559 454 'end_date' => 'membership_end_date',
861d11c4
DG
455 'end_frequency_interval' => '4',
456 'end_frequency_unit' => 'month',
457 'entity_status' => '',
458 'entity_value' => '',
459 'group_id' => '',
460 'is_active' => 1,
461 'is_repeat' => '1',
462 'mapping_id' => 4,
463 'msg_template_id' => '',
464 'recipient' => '',
465 'recipient_listing' => '',
466 'recipient_manual' => '',
467 'record_activity' => 1,
468 'repetition_frequency_interval' => '4',
469 'repetition_frequency_unit' => 'week',
470 'start_action_condition' => 'after',
471 'start_action_date' => 'membership_end_date',
472 'start_action_offset' => '2',
473 'start_action_unit' => 'month',
474 'subject' => 'subject sched_membership_end_2month',
475 );
567b2076 476 $this->fixtures['sched_membership_end_limit_to_none'] = array(
baa85770
EM
477 'name' => 'limit to none',
478 'title' => 'limit to none',
479 'absolute_date' => '',
480 'body_html' => '<p>body sched_membership_end_2month</p>',
481 'body_text' => 'body sched_membership_end_2month',
482 'end_action' => '',
483 'end_date' => '',
484 'end_frequency_interval' => '4',
485 'end_frequency_unit' => 'month',
486 'entity_status' => '',
487 'entity_value' => '',
488 'limit_to' => 0,
489 'group_id' => '',
490 'is_active' => 1,
491 'is_repeat' => '1',
492 'mapping_id' => 4,
493 'msg_template_id' => '',
494 'recipient' => '',
495 'recipient_listing' => '',
496 'recipient_manual' => '',
497 'record_activity' => 1,
498 'repetition_frequency_interval' => '4',
499 'repetition_frequency_unit' => 'week',
500 'start_action_condition' => 'after',
501 'start_action_date' => 'membership_end_date',
502 'start_action_offset' => '2',
503 'start_action_unit' => 'month',
504 'subject' => 'limit to none',
505 );
6a488035 506 $this->_setUp();
6a488035
TO
507 }
508
509 /**
510 * Tears down the fixture, for example, closes a network connection.
92c99a4a 511 *
6a488035 512 * This method is called after a test is executed.
6a488035 513 */
00be9182 514 public function tearDown() {
6a488035
TO
515 parent::tearDown();
516
517 $this->mut->clearMessages();
518 $this->mut->stop();
519 unset($this->mut);
92c99a4a
EM
520 $this->quickCleanup(array(
521 'civicrm_action_schedule',
522 'civicrm_action_log',
523 'civicrm_membership',
524 'civicrm_email',
525 ));
6a488035
TO
526 $this->_tearDown();
527 }
528
43ceab3f
TO
529 public function mailerExamples() {
530 $cases = array();
531
532 $manyTokensTmpl = implode(';;', array(
533 '{contact.display_name}', // basic contact token
534 '{contact.gender}', // funny legacy contact token
535 '{contact.gender_id}', // funny legacy contact token
536 '{domain.name}', // domain token
537 '{activity.activity_type}', // action-scheduler token
538 ));
539 $manyTokensExpected = 'test-member@example.com;;Female;;Female;;Second Domain;;Phone Call';
540
541 // In this example, we use a lot of tokens cutting across multiple components..
542 $cases[0] = array(
543 // Schedule definition.
544 array(
545 'subject' => "subj $manyTokensTmpl",
546 'body_html' => "html $manyTokensTmpl",
547 'body_text' => "text $manyTokensTmpl",
548 ),
549 // Assertions (regex).
550 array(
551 'from_name' => "/^FIXME\$/",
552 'from_email' => "/^info@EXAMPLE.ORG\$/",
553 'subject' => "/^subj $manyTokensExpected\$/",
554 'body_html' => "/^html $manyTokensExpected\$/",
555 'body_text' => "/^text $manyTokensExpected\$/",
556 ),
557 );
558
559 // In this example, we customize the from address.
560 $cases[1] = array(
561 // Schedule definition.
562 array(
563 'from_name' => 'Bob',
564 'from_email' => 'bob@example.org',
565 ),
566 // Assertions (regex).
567 array(
568 'from_name' => "/^Bob\$/",
569 'from_email' => "/^bob@example.org\$/",
570 ),
571 );
572
573 // In this example, we autoconvert HTML to text
574 $cases[2] = array(
575 // Schedule definition.
576 array(
577 'body_html' => '<p>Hello &amp; stuff.</p>',
578 'body_text' => '',
579 ),
580 // Assertions (regex).
581 array(
582 'body_html' => '/^' . preg_quote('<p>Hello &amp; stuff.</p>', '/') . '/',
583 'body_text' => '/^' . preg_quote('Hello & stuff.', '/') . '/',
584 ),
585 );
586
587 // In this example, we autoconvert HTML to text
588 $cases[3] = array(
589 // Schedule definition.
590 array(
591 'body_html' => '',
592 'body_text' => 'Hello world',
593 ),
594 // Assertions (regex).
595 array(
596 'body_html' => '/^--UNDEFINED--$/',
597 'body_text' => '/^Hello world$/',
598 ),
599 );
600
601 return $cases;
602 }
603
604 /**
605 * This generates a single mailing through the scheduled-reminder
606 * system (using an activity-reminder as a baseline) and
607 * checks that the resulting message satisfies various
608 * regular expressions.
609 *
610 * @param array $schedule
611 * Values to set/override in the schedule.
612 * Ex: array('subject' => 'Hello, {contact.first_name}!').
613 * @param array $patterns
614 * A list of regexes to compare with the actual email.
615 * Ex: array('subject' => '/^Hello, Alice!/').
616 * Keys: subject, body_text, body_html, from_name, from_email.
617 * @dataProvider mailerExamples
618 */
619 public function testMailer($schedule, $patterns) {
620 $actionSchedule = array_merge($this->fixtures['sched_activity_1day'], $schedule);
621 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
622 $this->assertTrue(is_numeric($actionScheduleDao->id));
623
624 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
625 $this->assertTrue(is_numeric($activity->id));
626 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
627 $activity->save();
628
629 $source['contact_id'] = $contact['id'];
630 $source['activity_id'] = $activity->id;
631 $source['record_type_id'] = 2;
632 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
633 $activityContact->save();
634
635 CRM_Utils_Time::setTime('2012-06-14 15:00:00');
636 $this->callAPISuccess('job', 'send_reminder', array());
637 $this->mut->assertRecipients(array(array('test-member@example.com')));
638 foreach ($this->mut->getAllMessages('ezc') as $message) {
639 /** @var ezcMail $message */
640
641 $messageArray = array();
642 $messageArray['subject'] = $message->subject;
643 $messageArray['from_name'] = $message->from->name;
644 $messageArray['from_email'] = $message->from->email;
645 $messageArray['body_text'] = '--UNDEFINED--';
646 $messageArray['body_html'] = '--UNDEFINED--';
647
648 foreach ($message->fetchParts() as $part) {
649 /** @var ezcMailText ezcMailText */
650 if ($part instanceof ezcMailText && $part->subType == 'html') {
651 $messageArray['body_html'] = $part->text;
652 }
653 if ($part instanceof ezcMailText && $part->subType == 'plain') {
654 $messageArray['body_text'] = $part->text;
655 }
656 }
657
658 foreach ($patterns as $field => $pattern) {
659 $this->assertRegExp($pattern, $messageArray[$field],
660 "Check that '$field'' matches regex. " . print_r(array('expected' => $patterns, 'actual' => $messageArray), 1));
661 }
662 }
663 $this->mut->clearMessages();
664
665 }
666
92c99a4a 667 public function testActivityDateTimeMatchNonRepeatableSchedule() {
cee19268 668 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day']);
6a488035
TO
669 $this->assertTrue(is_numeric($actionScheduleDao->id));
670
671 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
6a488035 672 $this->assertTrue(is_numeric($activity->id));
6c6e6187 673 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
6a488035
TO
674 $activity->save();
675
4f20f356 676 $source['contact_id'] = $contact['id'];
677 $source['activity_id'] = $activity->id;
678 $source['record_type_id'] = 2;
679 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
680 $activityContact->save();
681
6a488035 682 $this->assertCronRuns(array(
567b2076
EM
683 array(
684 // Before the 24-hour mark, no email
6a488035
TO
685 'time' => '2012-06-14 04:00:00',
686 'recipients' => array(),
f8c3594b 687 'subjects' => array(),
6a488035 688 ),
567b2076
EM
689 array(
690 // After the 24-hour mark, an email
6a488035
TO
691 'time' => '2012-06-14 15:00:00',
692 'recipients' => array(array('test-member@example.com')),
f8c3594b 693 'subjects' => array('1-Day (non-repeating) (about Phone Call)'),
6a488035 694 ),
567b2076
EM
695 array(
696 // Run cron again; message already sent
6a488035
TO
697 'time' => '',
698 'recipients' => array(),
699 ),
700 ));
701 }
702
92c99a4a 703 public function testActivityDateTimeMatchRepeatableSchedule() {
cee19268 704 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r']);
6a488035
TO
705 $this->assertTrue(is_numeric($actionScheduleDao->id));
706
707 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
708 $this->assertTrue(is_numeric($activity->id));
6c6e6187 709 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
6a488035
TO
710 $activity->save();
711
4f20f356 712 $source['contact_id'] = $contact['id'];
713 $source['activity_id'] = $activity->id;
6c6e6187 714 $source['record_type_id'] = 2;
4f20f356 715 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
716 $activityContact->save();
717
6a488035 718 $this->assertCronRuns(array(
567b2076
EM
719 array(
720 // Before the 24-hour mark, no email
6a488035
TO
721 'time' => '012-06-14 04:00:00',
722 'recipients' => array(),
f8c3594b 723 'subjects' => array(),
6a488035 724 ),
567b2076
EM
725 array(
726 // After the 24-hour mark, an email
6a488035
TO
727 'time' => '2012-06-14 15:00:00',
728 'recipients' => array(array('test-member@example.com')),
f8c3594b 729 'subjects' => array('1-Day (repeating) (about Phone Call)'),
6a488035 730 ),
567b2076
EM
731 array(
732 // Run cron 4 hours later; first message already sent
6a488035
TO
733 'time' => '2012-06-14 20:00:00',
734 'recipients' => array(),
f8c3594b 735 'subjects' => array(),
6a488035 736 ),
567b2076
EM
737 array(
738 // Run cron 6 hours later; send second message.
6a488035
TO
739 'time' => '2012-06-14 21:00:01',
740 'recipients' => array(array('test-member@example.com')),
f8c3594b 741 'subjects' => array('1-Day (repeating) (about Phone Call)'),
6a488035
TO
742 ),
743 ));
744 }
745
746 /**
747 * For contacts/activities which don't match the schedule filter,
748 * an email should *not* be sent.
749 */
750 // TODO // function testActivityDateTime_NonMatch() { }
751
752 /**
753 * For contacts/members which match schedule based on join date,
754 * an email should be sent.
755 */
92c99a4a 756 public function testMembershipJoinDateMatch() {
b29be8c2 757 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
6a488035 758 $this->assertTrue(is_numeric($membership->id));
bf308d29 759 $result = $this->callAPISuccess('Email', 'create', array(
6a488035
TO
760 'contact_id' => $membership->contact_id,
761 'email' => 'test-member@example.com',
762 'location_type_id' => 1,
92915c55 763 ));
6a488035
TO
764 $this->assertAPISuccess($result);
765
bf308d29 766 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
6a488035
TO
767 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
768 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 769 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
6a488035
TO
770 $this->assertTrue(is_numeric($actionScheduleDao->id));
771
772 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
773 $this->assertCronRuns(array(
567b2076
EM
774 array(
775 // Before the 2-week mark, no email.
6a488035
TO
776 'time' => '2012-03-28 01:00:00',
777 'recipients' => array(),
f8c3594b 778 'subjects' => array(),
6a488035 779 ),
567b2076
EM
780 array(
781 // After the 2-week mark, send an email.
6a488035
TO
782 'time' => '2012-03-29 01:00:00',
783 'recipients' => array(array('test-member@example.com')),
f8c3594b 784 'subjects' => array('subject sched_membership_join_2week (joined March 15th, 2012)'),
6a488035
TO
785 ),
786 ));
787 }
788
789 /**
442cf836
EM
790 * Test end date email sent.
791 *
6a488035
TO
792 * For contacts/members which match schedule based on join date,
793 * an email should be sent.
794 */
92c99a4a 795 public function testMembershipJoinDateNonMatch() {
6a488035
TO
796 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures['rolling_membership']);
797 $this->assertTrue(is_numeric($membership->id));
bf308d29 798 $result = $this->callAPISuccess('Email', 'create', array(
6a488035
TO
799 'contact_id' => $membership->contact_id,
800 'location_type_id' => 1,
801 'email' => 'test-member@example.com',
6a488035 802 ));
fe265b4e 803
6a488035
TO
804 // Add an alternative membership type, and only send messages for that type
805 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
806 $this->assertTrue(is_numeric($extraMembershipType->id));
cee19268 807 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_membership_join_2week']);
6a488035
TO
808 $this->assertTrue(is_numeric($actionScheduleDao->id));
809 $actionScheduleDao->entity_value = $extraMembershipType->id;
810 $actionScheduleDao->save();
811
812 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
813 $this->assertCronRuns(array(
567b2076
EM
814 array(
815 // After the 2-week mark, don't send email because we have different membership type.
6a488035
TO
816 'time' => '2012-03-29 01:00:00',
817 'recipients' => array(),
818 ),
819 ));
820 }
821
861d11c4 822 /**
442cf836 823 * Test that the first and SECOND notifications are sent out.
861d11c4 824 */
92c99a4a 825 public function testMembershipEndDateRepeat() {
861d11c4
DG
826 // creates membership with end_date = 20120615
827 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
828 $result = $this->callAPISuccess('Email', 'create', array(
829 'contact_id' => $membership->contact_id,
830 'email' => 'test-member@example.com',
831 ));
832 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
833
834 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
835 $actionSchedule['entity_value'] = $membership->membership_type_id;
836 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
837
838 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
839 $this->assertCronRuns(array(
567b2076
EM
840 array(
841 // After the 2-week mark, send an email.
861d11c4
DG
842 'time' => '2012-08-15 01:00:00',
843 'recipients' => array(array('test-member@example.com')),
844 ),
567b2076
EM
845 array(
846 // After the 2-week mark, send an email.
861d11c4
DG
847 'time' => '2012-09-12 01:00:00',
848 'recipients' => array(array('test-member@example.com')),
849 ),
850 ));
851 }
852
853 /**
442cf836
EM
854 * Test behaviour when date changes.
855 *
861d11c4
DG
856 * Test that the first notification is sent but the second is NOT sent if the end date changes in
857 * between
858 * see CRM-15376
859 */
92c99a4a 860 public function testMembershipEndDateRepeatChangedEndDate_CRM_15376() {
861d11c4
DG
861 // creates membership with end_date = 20120615
862 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
863 $this->callAPISuccess('Email', 'create', array(
864 'contact_id' => $membership->contact_id,
865 'email' => 'test-member@example.com',
866 ));
867 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
868
869 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
870 $actionSchedule['entity_value'] = $membership->membership_type_id;
871 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
872 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
873 $this->assertCronRuns(array(
567b2076
EM
874 array(
875 // After the 2-week mark, send an email.
861d11c4
DG
876 'time' => '2012-08-15 01:00:00',
877 'recipients' => array(array('test-member@example.com')),
878 ),
879 ));
880
442cf836 881 // Extend membership - reminder should NOT go out.
861d11c4
DG
882 $this->callAPISuccess('membership', 'create', array('id' => $membership->id, 'end_date' => '2014-01-01'));
883 $this->assertCronRuns(array(
442cf836
EM
884 array(
885 // After the 2-week mark, send an email.
861d11c4
DG
886 'time' => '2012-09-12 01:00:00',
887 'recipients' => array(),
888 ),
889 ));
890 }
891
6a488035 892 /**
442cf836
EM
893 * Test membership end date email sends.
894 *
6a488035
TO
895 * For contacts/members which match schedule based on end date,
896 * an email should be sent.
897 */
92c99a4a 898 public function testMembershipEndDateMatch() {
6a488035 899 // creates membership with end_date = 20120615
b29be8c2 900 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
6a488035 901 $this->assertTrue(is_numeric($membership->id));
bf308d29 902 $this->callAPISuccess('Email', 'create', array(
6a488035
TO
903 'contact_id' => $membership->contact_id,
904 'email' => 'test-member@example.com',
92915c55 905 ));
bf308d29 906 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
6a488035
TO
907
908 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
909 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 910 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
6a488035
TO
911 $this->assertTrue(is_numeric($actionScheduleDao->id));
912
913 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
914 $this->assertCronRuns(array(
442cf836
EM
915 array(
916 // Before the 2-week mark, no email.
6a488035 917 'time' => '2012-05-31 01:00:00',
442cf836
EM
918 // 'time' => '2012-06-01 01:00:00',
919 // FIXME: Is this the right boundary?
6a488035
TO
920 'recipients' => array(),
921 ),
442cf836
EM
922 array(
923 // After the 2-week mark, send an email.
6a488035
TO
924 'time' => '2012-06-01 01:00:00',
925 'recipients' => array(array('test-member@example.com')),
926 ),
927 ));
d2868251 928
929 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
930 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
931 $membership->end_date = '2012-09-15';
932 $membership->save();
933
934 //change the email id of chosen membership contact to assert
935 //recipient of not the previously sent mail but the new one
936 $result = $this->callAPISuccess('Email', 'create', array(
937 'is_primary' => 1,
938 'contact_id' => $membership->contact_id,
cbcb7579 939 'email' => 'member2@example.com',
d2868251 940 ));
941 $this->assertAPISuccess($result);
942
943 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
944 $this->assertCronRuns(array(
cbcb7579
TO
945 array(
946 // Before the 2-week mark, no email
d2868251 947 'time' => '2012-08-31 01:00:00',
948 'recipients' => array(),
cbcb7579
TO
949 ),
950 //array( // After the 2-week mark, send an email
951 //'time' => '2012-09-01 01:00:00',
952 //'recipients' => array(array('member2@example.com')),
953 //),
d2868251 954 ));
6a488035
TO
955 }
956
4b1efa1d 957
958 /**
442cf836
EM
959 * Test membership end date email.
960 *
6c6e6187
TO
961 * For contacts/members which match schedule based on end date,
962 * an email should be sent.
963 */
92c99a4a 964 public function testMembershipEndDateNoMatch() {
4b1efa1d 965 // creates membership with end_date = 20120615
5c4d6559 966 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 3)));
4b1efa1d 967 $this->assertTrue(is_numeric($membership->id));
6c6e6187 968 $result = $this->callAPISuccess('Email', 'create', array(
4b1efa1d 969 'contact_id' => $membership->contact_id,
970 'email' => 'test-member@example.com',
4b1efa1d 971 ));
bf308d29 972 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
4b1efa1d 973
974 $actionSchedule = $this->fixtures['sched_membership_end_2month'];
975 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 976 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
4b1efa1d 977 $this->assertTrue(is_numeric($actionScheduleDao->id));
978
979 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
980 $this->assertCronRuns(array(
442cf836
EM
981 array(
982 // Before the 2-week mark, no email.
4b1efa1d 983 'time' => '2012-05-31 01:00:00',
442cf836
EM
984 // 'time' => '2012-06-01 01:00:00',
985 // FIXME: Is this the right boundary?
4b1efa1d 986 'recipients' => array(),
987 ),
442cf836
EM
988 array(
989 // After the 2-week mark, send an email.
4b1efa1d 990 'time' => '2013-05-01 01:00:00',
991 'recipients' => array(),
992 ),
993 ));
994 }
995
92c99a4a 996 public function testContactBirthDateNoAnniv() {
bf308d29 997 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
998 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
999 $actionSchedule = $this->fixtures['sched_contact_bday_yesterday'];
1000 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1001 $this->assertTrue(is_numeric($actionScheduleDao->id));
1002 $this->assertCronRuns(array(
442cf836
EM
1003 array(
1004 // On the birthday, no email.
43030baf
AH
1005 'time' => '2005-07-07 01:00:00',
1006 'recipients' => array(),
1007 ),
442cf836
EM
1008 array(
1009 // The next day, send an email.
43030baf
AH
1010 'time' => '2005-07-08 20:00:00',
1011 'recipients' => array(array('test-bday@example.com')),
1012 ),
1013 ));
1014 }
1015
92c99a4a 1016 public function testContactBirthDateAnniversary() {
6c6e6187 1017 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
1018 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1019 $actionSchedule = $this->fixtures['sched_contact_bday_anniv'];
1020 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1021 $this->assertTrue(is_numeric($actionScheduleDao->id));
1022 $this->assertCronRuns(array(
92c99a4a
EM
1023 array(
1024 // On some random day, no email.
43030baf
AH
1025 'time' => '2014-03-07 01:00:00',
1026 'recipients' => array(),
1027 ),
92c99a4a
EM
1028 array(
1029 // On the eve of their 9th birthday, send an email.
43030baf
AH
1030 'time' => '2014-07-06 20:00:00',
1031 'recipients' => array(array('test-bday@example.com')),
1032 ),
1033 ));
1034 }
4b1efa1d 1035
92c99a4a 1036 public function testContactCustomDateNoAnniv() {
43030baf
AH
1037 $group = array(
1038 'title' => 'Test_Group',
1039 'name' => 'test_group',
1040 'extends' => array('Individual'),
1041 'style' => 'Inline',
6c6e6187 1042 'is_multiple' => FALSE,
43030baf 1043 'is_active' => 1,
43030baf 1044 );
bf308d29 1045 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 1046 $field = array(
43030baf
AH
1047 'label' => 'Graduation',
1048 'data_type' => 'Date',
1049 'html_type' => 'Select Date',
1050 'custom_group_id' => $createGroup['id'],
1051 );
bf308d29 1052 $createField = $this->callAPISuccess('custom_field', 'create', $field);
43030baf
AH
1053 $contactParams = $this->fixtures['contact'];
1054 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 1055 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
1056 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1057 $actionSchedule = $this->fixtures['sched_contact_grad_tomorrow'];
1058 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1059 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1060 $this->assertTrue(is_numeric($actionScheduleDao->id));
1061 $this->assertCronRuns(array(
92c99a4a
EM
1062 array(
1063 // On some random day, no email.
43030baf
AH
1064 'time' => '2014-03-07 01:00:00',
1065 'recipients' => array(),
1066 ),
92c99a4a
EM
1067 array(
1068 // On the eve of their graduation, send an email.
43030baf
AH
1069 'time' => '2013-12-15 20:00:00',
1070 'recipients' => array(array('test-member@example.com')),
1071 ),
1072 ));
6c6e6187 1073 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
43030baf 1074 }
92915c55 1075
4aff0253
AH
1076 public function testContactCreatedNoAnniv() {
1077 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1078 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1079 $actionSchedule = $this->fixtures['sched_contact_created_yesterday'];
1080 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1081 $this->assertTrue(is_numeric($actionScheduleDao->id));
1082 $this->assertCronRuns(array(
1083 array(
1084 // On the date created, no email.
1085 'time' => $contact['values'][$contact['id']]['created_date'],
1086 'recipients' => array(),
1087 ),
1088 array(
1089 // The next day, send an email.
1090 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['created_date'] . ' +1 day')),
1091 'recipients' => array(array('test-bday@example.com')),
1092 ),
1093 ));
1094 }
1095
1096 public function testContactModifiedAnniversary() {
1097 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1098 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1099 $actionSchedule = $this->fixtures['sched_contact_mod_anniv'];
1100 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1101 $this->assertTrue(is_numeric($actionScheduleDao->id));
1102 $this->assertCronRuns(array(
1103 array(
1104 // On some random day, no email.
a9ac9f6c 1105 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' -60 days')),
4aff0253
AH
1106 'recipients' => array(),
1107 ),
1108 array(
1109 // On the eve of 3 years after they were modified, send an email.
a9ac9f6c 1110 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' +3 years -23 hours')),
4aff0253
AH
1111 'recipients' => array(array('test-bday@example.com')),
1112 ),
1113 ));
1114 }
1115
baa85770 1116 /**
92c99a4a 1117 * Check that limit_to + an empty recipients doesn't sent to multiple contacts.
baa85770 1118 */
00be9182 1119 public function testMembershipLimitToNone() {
baa85770
EM
1120 // creates membership with end_date = 20120615
1121 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1122
1123 $this->assertTrue(is_numeric($membership->id));
1124 $result = $this->callAPISuccess('Email', 'create', array(
1125 'contact_id' => $membership->contact_id,
1126 'email' => 'member@example.com',
1127 ));
1128 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1129 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
1130
1131 $this->assertAPISuccess($result);
1132
1133 $actionSchedule = $this->fixtures['sched_membership_end_limit_to_none'];
1134 $actionSchedule['entity_value'] = $membership->membership_type_id;
1135 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1136 $this->assertTrue(is_numeric($actionScheduleDao->id));
1137
1138 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1139 $this->assertCronRuns(array(
92c99a4a
EM
1140 array(
1141 // Before the 2-week mark, no email.
baa85770
EM
1142 'time' => '2012-05-31 01:00:00',
1143 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
1144 'recipients' => array(),
1145 ),
1146 ));
1147 }
1148
cbcb7579 1149 public function testMembership_referenceDate() {
5c4d6559 1150 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1151
1152 $this->assertTrue(is_numeric($membership->id));
1153 $result = $this->callAPISuccess('Email', 'create', array(
1154 'contact_id' => $membership->contact_id,
1155 'email' => 'member@example.com',
1156 ));
1157
1158 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1159 $this->assertAPISuccess($result);
1160
1161 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1162 $actionSchedule['entity_value'] = $membership->membership_type_id;
1163 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1164 $this->assertTrue(is_numeric($actionScheduleDao->id));
1165
1166 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1167 $this->assertCronRuns(array(
cbcb7579
TO
1168 array(
1169 // After the 2-week mark, send an email
5c4d6559 1170 'time' => '2012-03-29 01:00:00',
1171 'recipients' => array(array('member@example.com')),
9c0fe051 1172 ),
cbcb7579
TO
1173 array(
1174 // After the 2-week 1day mark, don't send an email
9c0fe051 1175 'time' => '2012-03-30 01:00:00',
1176 'recipients' => array(),
1177 ),
5c4d6559 1178 ));
1179
1180 //check if reference date is set to membership's join date
1181 //as per the action_start_date chosen for current schedule reminder
1182 $this->assertEquals('2012-03-15',
1183 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $membership->contact_id, 'reference_date', 'contact_id')
1184 );
1185
e7c6a902 1186 //change current membership join date that may signifies as membership renewal activity
5c4d6559 1187 $membership->join_date = '2012-03-29';
1188 $membership->save();
1189
5c4d6559 1190 $this->assertCronRuns(array(
cbcb7579
TO
1191 array(
1192 // After the 13 days of the changed join date 2012-03-29, don't send an email
9c0fe051 1193 'time' => '2012-04-11 01:00:00',
cbcb7579
TO
1194 'recipients' => array(),
1195 ),
1196 array(
1197 // After the 2-week of the changed join date 2012-03-29, send an email
5c4d6559 1198 'time' => '2012-04-12 01:00:00',
cbcb7579 1199 'recipients' => array(array('member@example.com')),
5c4d6559 1200 ),
1201 ));
5c4d6559 1202 }
baa85770 1203
d2868251 1204 public function testMembershipOnMultipleReminder() {
1205 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
d2868251 1206
1207 $this->assertTrue(is_numeric($membership->id));
1208 $result = $this->callAPISuccess('Email', 'create', array(
1209 'contact_id' => $membership->contact_id,
1210 'email' => 'member@example.com',
1211 ));
cbcb7579 1212 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
d2868251 1213 $this->assertAPISuccess($result);
1214
1215 $actionScheduleBefore = $this->fixtures['sched_membership_end_2week']; // Send email 2 weeks before end_date
1216 $actionScheduleOn = $this->fixtures['sched_on_membership_end_date']; // Send email on end_date/expiry date
1217 $actionScheduleAfter = $this->fixtures['sched_after_1day_membership_end_date']; // Send email 1 day after end_date/grace period
1218 $actionScheduleBefore['entity_value'] = $actionScheduleOn['entity_value'] = $actionScheduleAfter['entity_value'] = $membership->membership_type_id;
1219 foreach (array('actionScheduleBefore', 'actionScheduleOn', 'actionScheduleAfter') as $value) {
1220 $$value = CRM_Core_BAO_ActionSchedule::add($$value);
1221 $this->assertTrue(is_numeric($$value->id));
1222 }
1223
1224 $this->assertCronRuns(
1225 array(
cbcb7579
TO
1226 array(
1227 // 1day 2weeks before membership end date(MED), don't send mail
d2868251 1228 'time' => '2012-05-31 01:00:00',
1229 'recipients' => array(),
1230 ),
cbcb7579
TO
1231 array(
1232 // 2 weeks before MED, send an email
d2868251 1233 'time' => '2012-06-01 01:00:00',
1234 'recipients' => array(array('member@example.com')),
1235 ),
cbcb7579
TO
1236 array(
1237 // 1day before MED, don't send mail
d2868251 1238 'time' => '2012-06-14 01:00:00',
1239 'recipients' => array(),
1240 ),
cbcb7579
TO
1241 array(
1242 // On MED, send an email
d2868251 1243 'time' => '2012-06-15 00:00:00',
1244 'recipients' => array(array('member@example.com')),
1245 ),
cbcb7579
TO
1246 array(
1247 // After 1day of MED, send an email
d2868251 1248 'time' => '2012-06-16 01:00:00',
1249 'recipients' => array(array('member@example.com')),
1250 ),
cbcb7579
TO
1251 array(
1252 // After 1day 1min of MED, don't send an email
d2868251 1253 'time' => '2012-06-17 00:01:00',
1254 'recipients' => array(),
1255 ),
cbcb7579
TO
1256 )
1257 );
d2868251 1258
1259 // Assert the timestamp as of when the emails of respective three reminders as configured
1260 // 2 weeks before, on and 1 day after MED, are sent
1261 $this->assertEquals('2012-06-01 01:00:00',
1262 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleBefore->id, 'action_date_time', 'action_schedule_id', TRUE));
1263 $this->assertEquals('2012-06-15 00:00:00',
1264 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleOn->id, 'action_date_time', 'action_schedule_id', TRUE));
1265 $this->assertEquals('2012-06-16 01:00:00',
1266 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleAfter->id, 'action_date_time', 'action_schedule_id', TRUE));
1267
e7c6a902 1268 //extend MED to 2 weeks after the current MED (that may signifies as membership renewal activity)
d2868251 1269 // and lets assert as of when the new set of reminders will be sent against their respective Schedule Reminders(SR)
9c0fe051 1270 $membership->end_date = '2012-06-20';
d2868251 1271 $membership->save();
d2868251 1272
9c0fe051 1273 $result = $this->callAPISuccess('Contact', 'get', array('id' => $membership->contact_id));
d2868251 1274 $this->assertCronRuns(
1275 array(
cbcb7579
TO
1276 array(
1277 // 1day 2weeks before membership end date(MED), don't send mail
9c0fe051 1278 'time' => '2012-06-05 01:00:00',
d2868251 1279 'recipients' => array(),
1280 ),
cbcb7579
TO
1281 array(
1282 // 2 weeks before MED, send an email
9c0fe051 1283 'time' => '2012-06-06 01:00:00',
1284 'recipients' => array(array('member@example.com')),
d2868251 1285 ),
cbcb7579
TO
1286 array(
1287 // 1day before MED, don't send mail
9c0fe051 1288 'time' => '2012-06-19 01:00:00',
d2868251 1289 'recipients' => array(),
1290 ),
cbcb7579
TO
1291 array(
1292 // On MED, send an email
9c0fe051 1293 'time' => '2012-06-20 00:00:00',
d2868251 1294 'recipients' => array(array('member@example.com')),
1295 ),
cbcb7579
TO
1296 array(
1297 // After 1day of MED, send an email
9c0fe051 1298 'time' => '2012-06-21 01:00:00',
d2868251 1299 'recipients' => array(array('member@example.com')),
1300 ),
cbcb7579
TO
1301 array(
1302 // After 1day 1min of MED, don't send an email
9c0fe051 1303 'time' => '2012-07-21 00:01:00',
d2868251 1304 'recipients' => array(),
1305 ),
d2868251 1306 ));
1307 }
1308
1309 public function testContactCustomDate_Anniv() {
43030baf
AH
1310 $group = array(
1311 'title' => 'Test_Group now',
1312 'name' => 'test_group_now',
1313 'extends' => array('Individual'),
1314 'style' => 'Inline',
6c6e6187 1315 'is_multiple' => FALSE,
43030baf 1316 'is_active' => 1,
43030baf 1317 );
bf308d29 1318 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 1319 $field = array(
43030baf
AH
1320 'label' => 'Graduation',
1321 'data_type' => 'Date',
1322 'html_type' => 'Select Date',
1323 'custom_group_id' => $createGroup['id'],
1324 );
bf308d29
EM
1325 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1326
43030baf
AH
1327 $contactParams = $this->fixtures['contact'];
1328 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 1329 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
1330 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1331 $actionSchedule = $this->fixtures['sched_contact_grad_anniv'];
1332 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1333 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1334 $this->assertTrue(is_numeric($actionScheduleDao->id));
1335 $this->assertCronRuns(array(
92c99a4a
EM
1336 array(
1337 // On some random day, no email.
43030baf
AH
1338 'time' => '2014-03-07 01:00:00',
1339 'recipients' => array(),
1340 ),
92c99a4a
EM
1341 array(
1342 // A week after their 5th anniversary of graduation, send an email.
43030baf
AH
1343 'time' => '2018-12-23 20:00:00',
1344 'recipients' => array(array('test-member@example.com')),
1345 ),
1346 ));
6c6e6187 1347 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
43030baf 1348 }
4b1efa1d 1349
6a488035
TO
1350 // TODO // function testMembershipEndDate_NonMatch() { }
1351 // TODO // function testEventTypeStartDate_Match() { }
1352 // TODO // function testEventTypeEndDate_Match() { }
1353 // TODO // function testEventNameStartDate_Match() { }
1354 // TODO // function testEventNameEndDate_Match() { }
1355
1356 /**
92c99a4a 1357 * Run a series of cron jobs and make an assertion about email deliveries.
6a488035 1358 *
16b10e64
CW
1359 * @param array $cronRuns
1360 * array specifying when to run cron and what messages to expect; each item is an array with keys:
1361 * - time: string, e.g. '2012-06-15 21:00:01'
1362 * - recipients: array(array(string)), list of email addresses which should receive messages
6a488035 1363 */
00be9182 1364 public function assertCronRuns($cronRuns) {
6a488035
TO
1365 foreach ($cronRuns as $cronRun) {
1366 CRM_Utils_Time::setTime($cronRun['time']);
bf308d29 1367 $this->callAPISuccess('job', 'send_reminder', array());
6a488035 1368 $this->mut->assertRecipients($cronRun['recipients']);
f8c3594b
TO
1369 if (array_key_exists('subjects', $cronRun)) {
1370 $this->mut->assertSubjects($cronRun['subjects']);
1371 }
6a488035
TO
1372 $this->mut->clearMessages();
1373 }
1374 }
1375
6a488035
TO
1376 /**
1377 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
1378 */
1379 private $_testObjects;
1380
1381 /**
1382 * Sets up the fixture, for example, opens a network connection.
92c99a4a 1383 *
6a488035 1384 * This method is called before a test is executed.
6a488035
TO
1385 */
1386 protected function _setUp() {
1387 $this->_testObjects = array();
1388 }
1389
1390 /**
1391 * Tears down the fixture, for example, closes a network connection.
92c99a4a 1392 *
6a488035 1393 * This method is called after a test is executed.
6a488035
TO
1394 */
1395 protected function _tearDown() {
1396 parent::tearDown();
1397 $this->deleteTestObjects();
1398 }
1399
1400 /**
1401 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
92c99a4a 1402 * created entities and provides for brainless cleanup.
6a488035
TO
1403 *
1404 * @see CRM_Core_DAO::createTestObject
92c99a4a 1405 *
1e1fdcf6
EM
1406 * @param $daoName
1407 * @param array $params
1408 * @param int $numObjects
1409 * @param bool $createOnly
92c99a4a
EM
1410 *
1411 * @return array|NULL|object
6a488035 1412 */
2da40d21 1413 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
6a488035
TO
1414 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
1415 if (is_array($objects)) {
1416 $this->registerTestObjects($objects);
0db6c3e1
TO
1417 }
1418 else {
6a488035
TO
1419 $this->registerTestObjects(array($objects));
1420 }
1421 return $objects;
1422 }
1423
1424 /**
5a4f6742
CW
1425 * @param array $objects
1426 * DAO or BAO objects.
6a488035 1427 */
00be9182 1428 public function registerTestObjects($objects) {
6a488035
TO
1429 //if (is_object($objects)) {
1430 // $objects = array($objects);
1431 //}
1432 foreach ($objects as $object) {
1433 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
1434 $this->_testObjects[$daoName][] = $object->id;
1435 }
1436 }
1437
00be9182 1438 public function deleteTestObjects() {
6a488035
TO
1439 // Note: You might argue that the FK relations between test
1440 // objects could make this problematic; however, it should
1441 // behave intuitively as long as we mentally split our
1442 // test-objects between the "manual/primary records"
1443 // and the "automatic/secondary records"
1444 foreach ($this->_testObjects as $daoName => $daoIds) {
1445 foreach ($daoIds as $daoId) {
1446 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
1447 }
1448 }
1449 $this->_testObjects = array();
1450 }
1451
1452}