Merge pull request #12011 from lcdservices/dev-financial-12
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / ActionScheduleTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * Class CRM_Core_BAO_ActionScheduleTest
30 * @group ActionSchedule
31 * @group headless
32 *
33 * There are additional tests for some specific entities in other classes:
34 * @see CRM_Activity_ActionMappingTest
35 * @see CRM_Contribute_ActionMapping_ByTypeTest
36 */
37 class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
38
39 /**
40 * @var CiviMailUtils
41 */
42 public $mut;
43
44 public function setUp() {
45 parent::setUp();
46
47 $this->mut = new CiviMailUtils($this, TRUE);
48
49 $this->fixtures['rolling_membership'] = array(
50 'membership_type_id' => array(
51 'period_type' => 'rolling',
52 'duration_unit' => 'month',
53 'duration_interval' => '3',
54 'is_active' => 1,
55 ),
56 'join_date' => '20120315',
57 'start_date' => '20120315',
58 'end_date' => '20120615',
59 'is_override' => 0,
60 );
61
62 $this->fixtures['rolling_membership_past'] = array(
63 'membership_type_id' => array(
64 'period_type' => 'rolling',
65 'duration_unit' => 'month',
66 'duration_interval' => '3',
67 'is_active' => 1,
68 ),
69 'join_date' => '20100310',
70 'start_date' => '20100310',
71 'end_date' => '20100610',
72 'is_override' => 'NULL',
73 );
74 $this->fixtures['participant'] = array(
75 'event_id' => array(
76 'is_active' => 1,
77 'is_template' => 0,
78 'title' => 'Example Event',
79 'start_date' => '20120315',
80 'end_date' => '20120615',
81 ),
82 'role_id' => '1', // Attendee.
83 'status_id' => '8', // No-show.
84 );
85
86 $this->fixtures['phonecall'] = array(
87 'status_id' => 1,
88 'activity_type_id' => 2,
89 'activity_date_time' => '20120615100000',
90 'is_current_revision' => 1,
91 'is_deleted' => 0,
92 );
93 $this->fixtures['contact'] = array(
94 'is_deceased' => 0,
95 'contact_type' => 'Individual',
96 'email' => 'test-member@example.com',
97 'gender_id' => 'Female',
98 'first_name' => 'Churmondleia',
99 'last_name' => 'Ōtākou',
100 );
101 $this->fixtures['contact_birthdate'] = array(
102 'is_deceased' => 0,
103 'contact_type' => 'Individual',
104 'email' => 'test-bday@example.com',
105 'birth_date' => '20050707',
106 );
107 $this->fixtures['sched_activity_1day'] = array(
108 'name' => 'One_Day_Phone_Call_Notice',
109 'title' => 'One Day Phone Call Notice',
110 'limit_to' => '1',
111 'absolute_date' => NULL,
112 'body_html' => '<p>1-Day (non-repeating) (for {activity.subject})</p>',
113 'body_text' => '1-Day (non-repeating) (for {activity.subject})',
114 'end_action' => NULL,
115 'end_date' => NULL,
116 'end_frequency_interval' => NULL,
117 'end_frequency_unit' => NULL,
118 'entity_status' => '1',
119 'entity_value' => '2',
120 'group_id' => NULL,
121 'is_active' => '1',
122 'is_repeat' => '0',
123 'mapping_id' => '1',
124 'msg_template_id' => NULL,
125 'recipient' => '2',
126 'recipient_listing' => NULL,
127 'recipient_manual' => NULL,
128 'record_activity' => 1,
129 'repetition_frequency_interval' => NULL,
130 'repetition_frequency_unit' => NULL,
131 'start_action_condition' => 'before',
132 'start_action_date' => 'activity_date_time',
133 'start_action_offset' => '1',
134 'start_action_unit' => 'day',
135 'subject' => '1-Day (non-repeating) (about {activity.activity_type})',
136 );
137 $this->fixtures['sched_activity_1day_r'] = array(
138 'name' => 'One_Day_Phone_Call_Notice_R',
139 'title' => 'One Day Phone Call Notice R',
140 'limit_to' => 1,
141 'absolute_date' => NULL,
142 'body_html' => '<p>1-Day (repeating)</p>',
143 'body_text' => '1-Day (repeating)',
144 'end_action' => 'after',
145 'end_date' => 'activity_date_time',
146 'end_frequency_interval' => '2',
147 'end_frequency_unit' => 'day',
148 'entity_status' => '1',
149 'entity_value' => '2',
150 'group_id' => NULL,
151 'is_active' => '1',
152 'is_repeat' => '1',
153 'mapping_id' => '1',
154 'msg_template_id' => NULL,
155 'recipient' => '2',
156 'recipient_listing' => NULL,
157 'recipient_manual' => NULL,
158 'record_activity' => NULL,
159 'repetition_frequency_interval' => '6',
160 'repetition_frequency_unit' => 'hour',
161 'start_action_condition' => 'before',
162 'start_action_date' => 'activity_date_time',
163 'start_action_offset' => '1',
164 'start_action_unit' => 'day',
165 'subject' => '1-Day (repeating) (about {activity.activity_type})',
166 );
167 $this->fixtures['sched_activity_1day_r_on_abs_date'] = array(
168 'name' => 'One_Day_Phone_Call_Notice_R',
169 'title' => 'One Day Phone Call Notice R',
170 'limit_to' => 1,
171 'absolute_date' => CRM_Utils_Date::processDate('20120614100000'),
172 'body_html' => '<p>1-Day (repeating)</p>',
173 'body_text' => '1-Day (repeating)',
174 'entity_status' => '1',
175 'entity_value' => '2',
176 'group_id' => NULL,
177 'is_active' => '1',
178 'is_repeat' => '1',
179 'mapping_id' => '1',
180 'msg_template_id' => NULL,
181 'recipient' => '2',
182 'recipient_listing' => NULL,
183 'recipient_manual' => NULL,
184 'record_activity' => NULL,
185 'repetition_frequency_interval' => '6',
186 'repetition_frequency_unit' => 'hour',
187 'end_action' => 'after',
188 'end_date' => 'activity_date_time',
189 'end_frequency_interval' => '2',
190 'end_frequency_unit' => 'day',
191 'start_action_condition' => '',
192 'start_action_date' => '',
193 'start_action_offset' => '',
194 'start_action_unit' => '',
195 'subject' => '1-Day (repeating) (about {activity.activity_type})',
196 );
197 $this->fixtures['sched_membership_join_2week'] = array(
198 'name' => 'sched_membership_join_2week',
199 'title' => 'sched_membership_join_2week',
200 'absolute_date' => '',
201 'body_html' => '<p>body sched_membership_join_2week</p>',
202 'body_text' => 'body sched_membership_join_2week',
203 'end_action' => '',
204 'end_date' => '',
205 'end_frequency_interval' => '',
206 'end_frequency_unit' => '',
207 'entity_status' => '',
208 'entity_value' => '',
209 'group_id' => '',
210 'is_active' => 1,
211 'is_repeat' => '0',
212 'mapping_id' => 4,
213 'msg_template_id' => '',
214 'recipient' => '',
215 'recipient_listing' => '',
216 'recipient_manual' => '',
217 'record_activity' => 1,
218 'repetition_frequency_interval' => '',
219 'repetition_frequency_unit' => '',
220 'start_action_condition' => 'after',
221 'start_action_date' => 'membership_join_date',
222 'start_action_offset' => '2',
223 'start_action_unit' => 'week',
224 'subject' => 'subject sched_membership_join_2week (joined {membership.join_date})',
225 );
226 $this->fixtures['sched_membership_end_2week'] = array(
227 'name' => 'sched_membership_end_2week',
228 'title' => 'sched_membership_end_2week',
229 'absolute_date' => '',
230 'body_html' => '<p>body sched_membership_end_2week</p>',
231 'body_text' => 'body sched_membership_end_2week',
232 'end_action' => '',
233 'end_date' => '',
234 'end_frequency_interval' => '',
235 'end_frequency_unit' => '',
236 'entity_status' => '',
237 'entity_value' => '',
238 'group_id' => '',
239 'is_active' => 1,
240 'is_repeat' => '0',
241 'mapping_id' => 4,
242 'msg_template_id' => '',
243 'recipient' => '',
244 'recipient_listing' => '',
245 'recipient_manual' => '',
246 'record_activity' => 1,
247 'repetition_frequency_interval' => '',
248 'repetition_frequency_unit' => '',
249 'start_action_condition' => 'before',
250 'start_action_date' => 'membership_end_date',
251 'start_action_offset' => '2',
252 'start_action_unit' => 'week',
253 'subject' => 'subject sched_membership_end_2week',
254 );
255 $this->fixtures['sched_on_membership_end_date'] = array(
256 'name' => 'sched_on_membership_end_date',
257 'title' => 'sched_on_membership_end_date',
258 'body_html' => '<p>Your membership expired today</p>',
259 'body_text' => 'Your membership expired today',
260 'is_active' => 1,
261 'mapping_id' => 4,
262 'record_activity' => 1,
263 'start_action_condition' => 'after',
264 'start_action_date' => 'membership_end_date',
265 'start_action_offset' => '0',
266 'start_action_unit' => 'hour',
267 'subject' => 'subject send reminder on membership_end_date',
268 );
269 $this->fixtures['sched_after_1day_membership_end_date'] = array(
270 'name' => 'sched_after_1day_membership_end_date',
271 'title' => 'sched_after_1day_membership_end_date',
272 'body_html' => '<p>Your membership expired yesterday</p>',
273 'body_text' => 'Your membership expired yesterday',
274 'is_active' => 1,
275 'mapping_id' => 4,
276 'record_activity' => 1,
277 'start_action_condition' => 'after',
278 'start_action_date' => 'membership_end_date',
279 'start_action_offset' => '1',
280 'start_action_unit' => 'day',
281 'subject' => 'subject send reminder on membership_end_date',
282 );
283
284 $this->fixtures['sched_membership_end_2month'] = array(
285 'name' => 'sched_membership_end_2month',
286 'title' => 'sched_membership_end_2month',
287 'absolute_date' => '',
288 'body_html' => '<p>body sched_membership_end_2month</p>',
289 'body_text' => 'body sched_membership_end_2month',
290 'end_action' => '',
291 'end_date' => '',
292 'end_frequency_interval' => '',
293 'end_frequency_unit' => '',
294 'entity_status' => '',
295 'entity_value' => '',
296 'group_id' => '',
297 'is_active' => 1,
298 'is_repeat' => '0',
299 'mapping_id' => 4,
300 'msg_template_id' => '',
301 'recipient' => '',
302 'recipient_listing' => '',
303 'recipient_manual' => '',
304 'record_activity' => 1,
305 'repetition_frequency_interval' => '',
306 'repetition_frequency_unit' => '',
307 'start_action_condition' => 'after',
308 'start_action_date' => 'membership_end_date',
309 'start_action_offset' => '2',
310 'start_action_unit' => 'month',
311 'subject' => 'subject sched_membership_end_2month',
312 );
313
314 $this->fixtures['sched_contact_bday_yesterday'] = array(
315 'name' => 'sched_contact_bday_yesterday',
316 'title' => 'sched_contact_bday_yesterday',
317 'absolute_date' => '',
318 'body_html' => '<p>you look like you were born yesterday!</p>',
319 'body_text' => 'you look like you were born yesterday!',
320 'end_action' => '',
321 'end_date' => '',
322 'end_frequency_interval' => '',
323 'end_frequency_unit' => '',
324 'entity_status' => 1,
325 'entity_value' => 'birth_date',
326 'group_id' => '',
327 'is_active' => 1,
328 'is_repeat' => '0',
329 'mapping_id' => 6,
330 'msg_template_id' => '',
331 'recipient' => '',
332 'recipient_listing' => '',
333 'recipient_manual' => '',
334 'record_activity' => 1,
335 'repetition_frequency_interval' => '',
336 'repetition_frequency_unit' => '',
337 'start_action_condition' => 'after',
338 'start_action_date' => 'date_field',
339 'start_action_offset' => '1',
340 'start_action_unit' => 'day',
341 'subject' => 'subject sched_contact_bday_yesterday',
342 );
343
344 $this->fixtures['sched_contact_bday_anniv'] = array(
345 'name' => 'sched_contact_bday_anniv',
346 'title' => 'sched_contact_bday_anniv',
347 'absolute_date' => '',
348 'body_html' => '<p>happy birthday!</p>',
349 'body_text' => 'happy birthday!',
350 'end_action' => '',
351 'end_date' => '',
352 'end_frequency_interval' => '',
353 'end_frequency_unit' => '',
354 'entity_status' => 2,
355 'entity_value' => 'birth_date',
356 'group_id' => '',
357 'is_active' => 1,
358 'is_repeat' => '0',
359 'mapping_id' => 6,
360 'msg_template_id' => '',
361 'recipient' => '',
362 'recipient_listing' => '',
363 'recipient_manual' => '',
364 'record_activity' => 1,
365 'repetition_frequency_interval' => '',
366 'repetition_frequency_unit' => '',
367 'start_action_condition' => 'before',
368 'start_action_date' => 'date_field',
369 'start_action_offset' => '1',
370 'start_action_unit' => 'day',
371 'subject' => 'subject sched_contact_bday_anniv',
372 );
373
374 $this->fixtures['sched_contact_grad_tomorrow'] = array(
375 'name' => 'sched_contact_grad_tomorrow',
376 'title' => 'sched_contact_grad_tomorrow',
377 'absolute_date' => '',
378 'body_html' => '<p>congratulations on your graduation!</p>',
379 'body_text' => 'congratulations on your graduation!',
380 'end_action' => '',
381 'end_date' => '',
382 'end_frequency_interval' => '',
383 'end_frequency_unit' => '',
384 'entity_status' => 1,
385 'group_id' => '',
386 'is_active' => 1,
387 'is_repeat' => '0',
388 'mapping_id' => 6,
389 'msg_template_id' => '',
390 'recipient' => '',
391 'recipient_listing' => '',
392 'recipient_manual' => '',
393 'record_activity' => 1,
394 'repetition_frequency_interval' => '',
395 'repetition_frequency_unit' => '',
396 'start_action_condition' => 'before',
397 'start_action_date' => 'date_field',
398 'start_action_offset' => '1',
399 'start_action_unit' => 'day',
400 'subject' => 'subject sched_contact_grad_tomorrow',
401 );
402
403 $this->fixtures['sched_contact_grad_anniv'] = array(
404 'name' => 'sched_contact_grad_anniv',
405 'title' => 'sched_contact_grad_anniv',
406 'absolute_date' => '',
407 'body_html' => '<p>dear alum, please send us money.</p>',
408 'body_text' => 'dear alum, please send us money.',
409 'end_action' => '',
410 'end_date' => '',
411 'end_frequency_interval' => '',
412 'end_frequency_unit' => '',
413 'entity_status' => 2,
414 'group_id' => '',
415 'is_active' => 1,
416 'is_repeat' => '0',
417 'mapping_id' => 6,
418 'msg_template_id' => '',
419 'recipient' => '',
420 'recipient_listing' => '',
421 'recipient_manual' => '',
422 'record_activity' => 1,
423 'repetition_frequency_interval' => '',
424 'repetition_frequency_unit' => '',
425 'start_action_condition' => 'after',
426 'start_action_date' => 'date_field',
427 'start_action_offset' => '1',
428 'start_action_unit' => 'week',
429 'subject' => 'subject sched_contact_grad_anniv',
430 );
431
432 $this->fixtures['sched_contact_created_yesterday'] = array(
433 'name' => 'sched_contact_created_yesterday',
434 'title' => 'sched_contact_created_yesterday',
435 'absolute_date' => '',
436 'body_html' => '<p>Your contact was created yesterday</p>',
437 'body_text' => 'Your contact was created yesterday!',
438 'end_action' => '',
439 'end_date' => '',
440 'end_frequency_interval' => '',
441 'end_frequency_unit' => '',
442 'entity_status' => 1,
443 'entity_value' => 'created_date',
444 'group_id' => '',
445 'is_active' => 1,
446 'is_repeat' => '0',
447 'mapping_id' => 6,
448 'msg_template_id' => '',
449 'recipient' => '',
450 'recipient_listing' => '',
451 'recipient_manual' => '',
452 'record_activity' => 1,
453 'repetition_frequency_interval' => '',
454 'repetition_frequency_unit' => '',
455 'start_action_condition' => 'after',
456 'start_action_date' => 'date_field',
457 'start_action_offset' => '1',
458 'start_action_unit' => 'day',
459 'subject' => 'subject sched_contact_created_yesterday',
460 );
461
462 $this->fixtures['sched_contact_mod_anniv'] = array(
463 'name' => 'sched_contact_mod_anniv',
464 'title' => 'sched_contact_mod_anniv',
465 'absolute_date' => '',
466 'body_html' => '<p>You last updated your data last year</p>',
467 'body_text' => 'Go update your stuff!',
468 'end_action' => '',
469 'end_date' => '',
470 'end_frequency_interval' => '',
471 'end_frequency_unit' => '',
472 'entity_status' => 2,
473 'entity_value' => 'modified_date',
474 'group_id' => '',
475 'is_active' => 1,
476 'is_repeat' => '0',
477 'mapping_id' => 6,
478 'msg_template_id' => '',
479 'recipient' => '',
480 'recipient_listing' => '',
481 'recipient_manual' => '',
482 'record_activity' => 1,
483 'repetition_frequency_interval' => '',
484 'repetition_frequency_unit' => '',
485 'start_action_condition' => 'before',
486 'start_action_date' => 'date_field',
487 'start_action_offset' => '1',
488 'start_action_unit' => 'day',
489 'subject' => 'subject sched_contact_mod_anniv',
490 );
491
492 $this->fixtures['sched_eventtype_start_1week_before'] = array(
493 'name' => 'sched_eventtype_start_1week_before',
494 'title' => 'sched_eventtype_start_1week_before',
495 'absolute_date' => '',
496 'body_html' => '<p>body sched_eventtype_start_1week_before ({event.title})</p>',
497 'body_text' => 'body sched_eventtype_start_1week_before ({event.title})',
498 'end_action' => '',
499 'end_date' => '',
500 'end_frequency_interval' => '',
501 'end_frequency_unit' => '',
502 'entity_status' => '', // participant status id
503 'entity_value' => '', // event type id
504 'group_id' => '',
505 'is_active' => 1,
506 'is_repeat' => '0',
507 'mapping_id' => 2, // event type
508 'msg_template_id' => '',
509 'recipient' => '',
510 'recipient_listing' => '',
511 'recipient_manual' => '',
512 'record_activity' => 1,
513 'repetition_frequency_interval' => '',
514 'repetition_frequency_unit' => '',
515 'start_action_condition' => 'before',
516 'start_action_date' => 'event_start_date',
517 'start_action_offset' => '1',
518 'start_action_unit' => 'week',
519 'subject' => 'subject sched_eventtype_start_1week_before ({event.title})',
520 );
521 $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'] = array(
522 'name' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
523 'title' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
524 'absolute_date' => '',
525 'body_html' => '<p>body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}</p>',
526 'body_text' => 'body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
527 'end_action' => 'after',
528 'end_date' => 'event_end_date',
529 'end_frequency_interval' => '3',
530 'end_frequency_unit' => 'month',
531 'entity_status' => '', // participant status id
532 'entity_value' => '', // event type id
533 'group_id' => '',
534 'is_active' => 1,
535 'is_repeat' => '1',
536 'mapping_id' => 2, // event type
537 'msg_template_id' => '',
538 'recipient' => '',
539 'recipient_listing' => '',
540 'recipient_manual' => '',
541 'record_activity' => 1,
542 'repetition_frequency_interval' => '2',
543 'repetition_frequency_unit' => 'week',
544 'start_action_condition' => 'after',
545 'start_action_date' => 'event_end_date',
546 'start_action_offset' => '2',
547 'start_action_unit' => 'month',
548 'subject' => 'subject sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
549 );
550
551 $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'] = array(
552 'name' => 'sched_membership_end_2month',
553 'title' => 'sched_membership_end_2month',
554 'absolute_date' => '',
555 'body_html' => '<p>body sched_membership_end_2month</p>',
556 'body_text' => 'body sched_membership_end_2month',
557 'end_action' => '',
558 'end_date' => 'membership_end_date',
559 'end_frequency_interval' => '4',
560 'end_frequency_unit' => 'month',
561 'entity_status' => '',
562 'entity_value' => '',
563 'group_id' => '',
564 'is_active' => 1,
565 'is_repeat' => '1',
566 'mapping_id' => 4,
567 'msg_template_id' => '',
568 'recipient' => '',
569 'recipient_listing' => '',
570 'recipient_manual' => '',
571 'record_activity' => 1,
572 'repetition_frequency_interval' => '4',
573 'repetition_frequency_unit' => 'week',
574 'start_action_condition' => 'after',
575 'start_action_date' => 'membership_end_date',
576 'start_action_offset' => '2',
577 'start_action_unit' => 'month',
578 'subject' => 'subject sched_membership_end_2month',
579 );
580 $this->fixtures['sched_membership_end_limit_to_none'] = array(
581 'name' => 'limit to none',
582 'title' => 'limit to none',
583 'absolute_date' => '',
584 'body_html' => '<p>body sched_membership_end_2month</p>',
585 'body_text' => 'body sched_membership_end_2month',
586 'end_action' => '',
587 'end_date' => '',
588 'end_frequency_interval' => '4',
589 'end_frequency_unit' => 'month',
590 'entity_status' => '',
591 'entity_value' => '',
592 'limit_to' => 0,
593 'group_id' => '',
594 'is_active' => 1,
595 'is_repeat' => '1',
596 'mapping_id' => 4,
597 'msg_template_id' => '',
598 'recipient' => '',
599 'recipient_listing' => '',
600 'recipient_manual' => '',
601 'record_activity' => 1,
602 'repetition_frequency_interval' => '4',
603 'repetition_frequency_unit' => 'week',
604 'start_action_condition' => 'after',
605 'start_action_date' => 'membership_end_date',
606 'start_action_offset' => '2',
607 'start_action_unit' => 'month',
608 'subject' => 'limit to none',
609 );
610 $this->fixtures['sched_on_membership_end_date_repeat_interval'] = array(
611 'name' => 'sched_on_membership_end_date',
612 'title' => 'sched_on_membership_end_date',
613 'body_html' => '<p>Your membership expired 1 unit ago</p>',
614 'body_text' => 'Your membership expired 1 unit ago',
615 'end_frequency_interval' => 10,
616 'end_frequency_unit' => 'year',
617 'is_active' => 1,
618 'is_repeat' => TRUE,
619 'mapping_id' => 4,
620 'record_activity' => 1,
621 'start_action_condition' => 'after',
622 'start_action_date' => 'membership_end_date',
623 'start_action_offset' => '0',
624 'start_action_unit' => 'hour',
625 'subject' => 'subject send reminder every unit after membership_end_date',
626 );
627
628 $customGroup = $this->callAPISuccess('CustomGroup', 'create', array(
629 'title' => ts('Test Contact Custom group'),
630 'name' => 'test_contact_cg',
631 'extends' => 'Contact',
632 'domain_id' => CRM_Core_Config::domainID(),
633 'is_active' => 1,
634 'collapse_adv_display' => 0,
635 'collapse_display' => 0,
636 ));
637 $customField = $this->callAPISuccess('CustomField', 'create', array(
638 'label' => 'Test Text',
639 'data_type' => 'String',
640 'html_type' => 'Text',
641 'custom_group_id' => $customGroup['id'],
642 ));
643 $this->fixtures['contact_custom_token'] = array(
644 'id' => $customField['id'],
645 'token' => sprintf('{contact.custom_%s}', $customField['id']),
646 'name' => sprintf('custom_%s', $customField['id']),
647 'value' => 'text ' . substr(sha1(rand()), 0, 7),
648 );
649
650 $this->_setUp();
651 }
652
653 /**
654 * Tears down the fixture, for example, closes a network connection.
655 *
656 * This method is called after a test is executed.
657 */
658 public function tearDown() {
659 parent::tearDown();
660 $this->mut->clearMessages();
661 $this->mut->stop();
662 unset($this->mut);
663 $this->quickCleanup(array(
664 'civicrm_action_schedule',
665 'civicrm_action_log',
666 'civicrm_membership',
667 'civicrm_participant',
668 'civicrm_event',
669 'civicrm_email',
670 ));
671 $this->callAPISuccess('CustomField', 'delete', array('id' => $this->fixtures['contact_custom_token']['id']));
672 $this->callAPISuccess('CustomGroup', 'delete', array(
673 'id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', 'test_contact_cg', 'id', 'name'),
674 ));
675 $this->_tearDown();
676 }
677
678 public function mailerExamples() {
679 $cases = array();
680
681 // Some tokens - short as subject has 128char limit in DB.
682 $someTokensTmpl = implode(';;', array(
683 '{contact.display_name}', // basic contact token
684 '{contact.gender}', // funny legacy contact token
685 '{contact.gender_id}', // funny legacy contact token
686 '{domain.name}', // domain token
687 '{activity.activity_type}', // action-scheduler token
688 ));
689 // Further tokens can be tested in the body text/html.
690 $manyTokensTmpl = implode(';;', array(
691 $someTokensTmpl,
692 '{contact.email_greeting}',
693 $this->fixture['contact_custom_token']['token'],
694 ));
695 // Note: The behavior of domain-tokens on a scheduled reminder is undefined. All we
696 // can really do is check that it has something.
697 $someTokensExpected = 'Churmondleia Ōtākou;;Female;;Female;;[a-zA-Z0-9 ]+;;Phone Call';
698 $manyTokensExpected = sprintf('%s;;Dear Churmondleia;;%s', $someTokensExpected, $this->fixture['contact_custom_token']['value']);
699
700 // In this example, we use a lot of tokens cutting across multiple components.
701 $cases[0] = array(
702 // Schedule definition.
703 array(
704 'subject' => "subj $someTokensTmpl",
705 'body_html' => "html $manyTokensTmpl",
706 'body_text' => "text $manyTokensTmpl",
707 ),
708 // Assertions (regex).
709 array(
710 'from_name' => "/^FIXME\$/",
711 'from_email' => "/^info@EXAMPLE.ORG\$/",
712 'subject' => "/^subj $someTokensExpected\$/",
713 'body_html' => "/^html $manyTokensExpected\$/",
714 'body_text' => "/^text $manyTokensExpected\$/",
715 ),
716 );
717
718 // In this example, we customize the from address.
719 $cases[1] = array(
720 // Schedule definition.
721 array(
722 'from_name' => 'Bob',
723 'from_email' => 'bob@example.org',
724 ),
725 // Assertions (regex).
726 array(
727 'from_name' => "/^Bob\$/",
728 'from_email' => "/^bob@example.org\$/",
729 ),
730 );
731
732 // In this example, we autoconvert HTML to text
733 $cases[2] = array(
734 // Schedule definition.
735 array(
736 'body_html' => '<p>Hello &amp; stuff.</p>',
737 'body_text' => '',
738 ),
739 // Assertions (regex).
740 array(
741 'body_html' => '/^' . preg_quote('<p>Hello &amp; stuff.</p>', '/') . '/',
742 'body_text' => '/^' . preg_quote('Hello & stuff.', '/') . '/',
743 ),
744 );
745
746 // In this example, we autoconvert HTML to text
747 $cases[3] = array(
748 // Schedule definition.
749 array(
750 'body_html' => '',
751 'body_text' => 'Hello world',
752 ),
753 // Assertions (regex).
754 array(
755 'body_html' => '/^--UNDEFINED--$/',
756 'body_text' => '/^Hello world$/',
757 ),
758 );
759
760 return $cases;
761 }
762
763 /**
764 * This generates a single mailing through the scheduled-reminder
765 * system (using an activity-reminder as a baseline) and
766 * checks that the resulting message satisfies various
767 * regular expressions.
768 *
769 * @param array $schedule
770 * Values to set/override in the schedule.
771 * Ex: array('subject' => 'Hello, {contact.first_name}!').
772 * @param array $patterns
773 * A list of regexes to compare with the actual email.
774 * Ex: array('subject' => '/^Hello, Alice!/').
775 * Keys: subject, body_text, body_html, from_name, from_email.
776 * @dataProvider mailerExamples
777 */
778 public function testMailer($schedule, $patterns) {
779 $actionSchedule = array_merge($this->fixtures['sched_activity_1day'], $schedule);
780 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
781 $this->assertTrue(is_numeric($actionScheduleDao->id));
782
783 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
784 $this->assertTrue(is_numeric($activity->id));
785 $contact = $this->callAPISuccess('contact', 'create', array_merge(
786 $this->fixtures['contact'],
787 array(
788 $this->fixtures['contact_custom_token']['name'] => $this->fixtures['contact_custom_token']['value'],
789 )
790 ));
791 $activity->save();
792
793 $source['contact_id'] = $contact['id'];
794 $source['activity_id'] = $activity->id;
795 $source['record_type_id'] = 2;
796 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
797 $activityContact->save();
798
799 CRM_Utils_Time::setTime('2012-06-14 15:00:00');
800 $this->callAPISuccess('job', 'send_reminder', array());
801 $this->mut->assertRecipients(array(array('test-member@example.com')));
802 foreach ($this->mut->getAllMessages('ezc') as $message) {
803 /** @var ezcMail $message */
804
805 $messageArray = array();
806 $messageArray['subject'] = $message->subject;
807 $messageArray['from_name'] = $message->from->name;
808 $messageArray['from_email'] = $message->from->email;
809 $messageArray['body_text'] = '--UNDEFINED--';
810 $messageArray['body_html'] = '--UNDEFINED--';
811
812 foreach ($message->fetchParts() as $part) {
813 /** @var ezcMailText ezcMailText */
814 if ($part instanceof ezcMailText && $part->subType == 'html') {
815 $messageArray['body_html'] = $part->text;
816 }
817 if ($part instanceof ezcMailText && $part->subType == 'plain') {
818 $messageArray['body_text'] = $part->text;
819 }
820 }
821
822 foreach ($patterns as $field => $pattern) {
823 $this->assertRegExp($pattern, $messageArray[$field],
824 "Check that '$field'' matches regex. " . print_r(array('expected' => $patterns, 'actual' => $messageArray), 1));
825 }
826 }
827 $this->mut->clearMessages();
828 }
829
830 public function testActivityDateTimeMatchNonRepeatableSchedule() {
831 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day']);
832 $this->assertTrue(is_numeric($actionScheduleDao->id));
833
834 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
835 $this->assertTrue(is_numeric($activity->id));
836 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
837 $activity->subject = "Test subject for Phonecall";
838 $activity->save();
839
840 $source['contact_id'] = $contact['id'];
841 $source['activity_id'] = $activity->id;
842 $source['record_type_id'] = 2;
843 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
844 $activityContact->save();
845
846 $this->assertCronRuns(array(
847 array(
848 // Before the 24-hour mark, no email
849 'time' => '2012-06-14 04:00:00',
850 'recipients' => array(),
851 'subjects' => array(),
852 ),
853 array(
854 // After the 24-hour mark, an email
855 'time' => '2012-06-14 15:00:00',
856 'recipients' => array(array('test-member@example.com')),
857 'subjects' => array('1-Day (non-repeating) (about Phone Call)'),
858 ),
859 array(
860 // Run cron again; message already sent
861 'time' => '',
862 'recipients' => array(),
863 ),
864 ));
865 $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, FALSE, FALSE, 'name');
866 $activityDAO = new CRM_Activity_DAO_Activity();
867 $activityDAO->source_record_id = $activity->id;
868 $activityDAO->activity_type_id = array_search('Reminder Sent', $activityTypes);
869 $activityDAO->find();
870 while ($activityDAO->fetch()) {
871 $this->assertContains($activity->subject, $activityDAO->details);
872 }
873 }
874
875 public function testActivityDateTimeMatchRepeatableSchedule() {
876 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r']);
877 $this->assertTrue(is_numeric($actionScheduleDao->id));
878
879 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
880 $this->assertTrue(is_numeric($activity->id));
881 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
882 $activity->save();
883
884 $source['contact_id'] = $contact['id'];
885 $source['activity_id'] = $activity->id;
886 $source['record_type_id'] = 2;
887 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
888 $activityContact->save();
889
890 $this->assertCronRuns(array(
891 array(
892 // Before the 24-hour mark, no email
893 'time' => '012-06-14 04:00:00',
894 'recipients' => array(),
895 'subjects' => array(),
896 ),
897 array(
898 // After the 24-hour mark, an email
899 'time' => '2012-06-14 15:00:00',
900 'recipients' => array(array('test-member@example.com')),
901 'subjects' => array('1-Day (repeating) (about Phone Call)'),
902 ),
903 array(
904 // Run cron 4 hours later; first message already sent
905 'time' => '2012-06-14 20:00:00',
906 'recipients' => array(),
907 'subjects' => array(),
908 ),
909 array(
910 // Run cron 6 hours later; send second message.
911 'time' => '2012-06-14 21:00:01',
912 'recipients' => array(array('test-member@example.com')),
913 'subjects' => array('1-Day (repeating) (about Phone Call)'),
914 ),
915 ));
916 }
917
918 public function testActivityDateTimeMatchRepeatableScheduleOnAbsDate() {
919 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r_on_abs_date']);
920 $this->assertTrue(is_numeric($actionScheduleDao->id));
921
922 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
923 $this->assertTrue(is_numeric($activity->id));
924 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
925 $activity->save();
926
927 $source['contact_id'] = $contact['id'];
928 $source['activity_id'] = $activity->id;
929 $source['record_type_id'] = 2;
930 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
931 $activityContact->save();
932
933 $this->assertCronRuns(array(
934 array(
935 // Before the 24-hour mark, no email
936 'time' => '2012-06-13 04:00:00',
937 'recipients' => array(),
938 'subjects' => array(),
939 ),
940 array(
941 // On absolute date set on 2012-06-14
942 'time' => '2012-06-14 00:00:00',
943 'recipients' => array(array('test-member@example.com')),
944 'subjects' => array('1-Day (repeating) (about Phone Call)'),
945 ),
946 array(
947 // Run cron 4 hours later; first message already sent
948 'time' => '2012-06-14 04:00:00',
949 'recipients' => array(),
950 'subjects' => array(),
951 ),
952 array(
953 // Run cron 6 hours later; send second message.
954 'time' => '2012-06-14 06:00:01',
955 'recipients' => array(array('test-member@example.com')),
956 'subjects' => array('1-Day (repeating) (about Phone Call)'),
957 ),
958 ));
959 }
960
961 /**
962 * For contacts/activities which don't match the schedule filter,
963 * an email should *not* be sent.
964 */
965 // TODO // function testActivityDateTime_NonMatch() { }
966
967 /**
968 * For contacts/members which match schedule based on join date,
969 * an email should be sent.
970 */
971 public function testMembershipJoinDateMatch() {
972 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
973 $this->assertTrue(is_numeric($membership->id));
974 $result = $this->callAPISuccess('Email', 'create', array(
975 'contact_id' => $membership->contact_id,
976 'email' => 'test-member@example.com',
977 'location_type_id' => 1,
978 ));
979 $this->assertAPISuccess($result);
980
981 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
982 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
983 $actionSchedule['entity_value'] = $membership->membership_type_id;
984 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
985 $this->assertTrue(is_numeric($actionScheduleDao->id));
986
987 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
988 $this->assertCronRuns(array(
989 array(
990 // Before the 2-week mark, no email.
991 'time' => '2012-03-28 01:00:00',
992 'recipients' => array(),
993 'subjects' => array(),
994 ),
995 array(
996 // After the 2-week mark, send an email.
997 'time' => '2012-03-29 01:00:00',
998 'recipients' => array(array('test-member@example.com')),
999 'subjects' => array('subject sched_membership_join_2week (joined March 15th, 2012)'),
1000 ),
1001 ));
1002 }
1003
1004 /**
1005 * Test end date email sent.
1006 *
1007 * For contacts/members which match schedule based on join date,
1008 * an email should be sent.
1009 */
1010 public function testMembershipJoinDateNonMatch() {
1011 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures['rolling_membership']);
1012 $this->assertTrue(is_numeric($membership->id));
1013 $result = $this->callAPISuccess('Email', 'create', array(
1014 'contact_id' => $membership->contact_id,
1015 'location_type_id' => 1,
1016 'email' => 'test-member@example.com',
1017 ));
1018
1019 // Add an alternative membership type, and only send messages for that type
1020 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
1021 $this->assertTrue(is_numeric($extraMembershipType->id));
1022 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_membership_join_2week']);
1023 $this->assertTrue(is_numeric($actionScheduleDao->id));
1024 $actionScheduleDao->entity_value = $extraMembershipType->id;
1025 $actionScheduleDao->save();
1026
1027 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1028 $this->assertCronRuns(array(
1029 array(
1030 // After the 2-week mark, don't send email because we have different membership type.
1031 'time' => '2012-03-29 01:00:00',
1032 'recipients' => array(),
1033 ),
1034 ));
1035 }
1036
1037 /**
1038 * Test that the first and SECOND notifications are sent out.
1039 */
1040 public function testMembershipEndDateRepeat() {
1041 // creates membership with end_date = 20120615
1042 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1043 $result = $this->callAPISuccess('Email', 'create', array(
1044 'contact_id' => $membership->contact_id,
1045 'email' => 'test-member@example.com',
1046 ));
1047 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1048
1049 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1050 $actionSchedule['entity_value'] = $membership->membership_type_id;
1051 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1052
1053 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1054 $this->assertCronRuns(array(
1055 array(
1056 // After the 2-week mark, send an email.
1057 'time' => '2012-08-15 01:00:00',
1058 'recipients' => array(array('test-member@example.com')),
1059 ),
1060 array(
1061 // After the 2-week mark, send an email.
1062 'time' => '2012-09-12 01:00:00',
1063 'recipients' => array(array('test-member@example.com')),
1064 ),
1065 ));
1066 }
1067
1068 /**
1069 * Test behaviour when date changes.
1070 *
1071 * Test that the first notification is sent but the second is NOT sent if the end date changes in
1072 * between
1073 * see CRM-15376
1074 */
1075 public function testMembershipEndDateRepeatChangedEndDate_CRM_15376() {
1076 // creates membership with end_date = 20120615
1077 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1078 $this->callAPISuccess('Email', 'create', array(
1079 'contact_id' => $membership->contact_id,
1080 'email' => 'test-member@example.com',
1081 ));
1082 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1083
1084 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1085 $actionSchedule['entity_value'] = $membership->membership_type_id;
1086 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1087 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1088 $this->assertCronRuns(array(
1089 array(
1090 // After the 2-week mark, send an email.
1091 'time' => '2012-08-15 01:00:00',
1092 'recipients' => array(array('test-member@example.com')),
1093 ),
1094 ));
1095
1096 // Extend membership - reminder should NOT go out.
1097 $this->callAPISuccess('membership', 'create', array('id' => $membership->id, 'end_date' => '2014-01-01'));
1098 $this->assertCronRuns(array(
1099 array(
1100 // After the 2-week mark, send an email.
1101 'time' => '2012-09-12 01:00:00',
1102 'recipients' => array(),
1103 ),
1104 ));
1105 }
1106
1107 /**
1108 * Test membership end date email sends.
1109 *
1110 * For contacts/members which match schedule based on end date,
1111 * an email should be sent.
1112 */
1113 public function testMembershipEndDateMatch() {
1114 // creates membership with end_date = 20120615
1115 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1116 $this->assertTrue(is_numeric($membership->id));
1117 $this->callAPISuccess('Email', 'create', array(
1118 'contact_id' => $membership->contact_id,
1119 'email' => 'test-member@example.com',
1120 ));
1121 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1122
1123 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
1124 $actionSchedule['entity_value'] = $membership->membership_type_id;
1125 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1126 $this->assertTrue(is_numeric($actionScheduleDao->id));
1127
1128 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1129 $this->assertCronRuns(array(
1130 array(
1131 // Before the 2-week mark, no email.
1132 'time' => '2012-05-31 01:00:00',
1133 // 'time' => '2012-06-01 01:00:00',
1134 // FIXME: Is this the right boundary?
1135 'recipients' => array(),
1136 ),
1137 array(
1138 // After the 2-week mark, send an email.
1139 'time' => '2012-06-01 01:00:00',
1140 'recipients' => array(array('test-member@example.com')),
1141 ),
1142 ));
1143
1144 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
1145 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
1146 $membership->end_date = '2012-09-15';
1147 $membership->save();
1148
1149 //change the email id of chosen membership contact to assert
1150 //recipient of not the previously sent mail but the new one
1151 $result = $this->callAPISuccess('Email', 'create', array(
1152 'is_primary' => 1,
1153 'contact_id' => $membership->contact_id,
1154 'email' => 'member2@example.com',
1155 ));
1156 $this->assertAPISuccess($result);
1157
1158 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
1159 $this->assertCronRuns(array(
1160 array(
1161 // Before the 2-week mark, no email
1162 'time' => '2012-08-31 01:00:00',
1163 'recipients' => array(),
1164 ),
1165 //array( // After the 2-week mark, send an email
1166 //'time' => '2012-09-01 01:00:00',
1167 //'recipients' => array(array('member2@example.com')),
1168 //),
1169 ));
1170 }
1171
1172
1173 /**
1174 * Test membership end date email.
1175 *
1176 * For contacts/members which match schedule based on end date,
1177 * an email should be sent.
1178 */
1179 public function testMembershipEndDateNoMatch() {
1180 // creates membership with end_date = 20120615
1181 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 3)));
1182 $this->assertTrue(is_numeric($membership->id));
1183 $result = $this->callAPISuccess('Email', 'create', array(
1184 'contact_id' => $membership->contact_id,
1185 'email' => 'test-member@example.com',
1186 ));
1187 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1188
1189 $actionSchedule = $this->fixtures['sched_membership_end_2month'];
1190 $actionSchedule['entity_value'] = $membership->membership_type_id;
1191 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1192 $this->assertTrue(is_numeric($actionScheduleDao->id));
1193
1194 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1195 $this->assertCronRuns(array(
1196 array(
1197 // Before the 2-week mark, no email.
1198 'time' => '2012-05-31 01:00:00',
1199 // 'time' => '2012-06-01 01:00:00',
1200 // FIXME: Is this the right boundary?
1201 'recipients' => array(),
1202 ),
1203 array(
1204 // After the 2-week mark, send an email.
1205 'time' => '2013-05-01 01:00:00',
1206 'recipients' => array(),
1207 ),
1208 ));
1209 }
1210
1211 public function testContactBirthDateNoAnniv() {
1212 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1213 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1214 $actionSchedule = $this->fixtures['sched_contact_bday_yesterday'];
1215 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1216 $this->assertTrue(is_numeric($actionScheduleDao->id));
1217 $this->assertCronRuns(array(
1218 array(
1219 // On the birthday, no email.
1220 'time' => '2005-07-07 01:00:00',
1221 'recipients' => array(),
1222 ),
1223 array(
1224 // The next day, send an email.
1225 'time' => '2005-07-08 20:00:00',
1226 'recipients' => array(array('test-bday@example.com')),
1227 ),
1228 ));
1229 }
1230
1231 public function testContactBirthDateAnniversary() {
1232 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1233 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1234 $actionSchedule = $this->fixtures['sched_contact_bday_anniv'];
1235 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1236 $this->assertTrue(is_numeric($actionScheduleDao->id));
1237 $this->assertCronRuns(array(
1238 array(
1239 // On some random day, no email.
1240 'time' => '2014-03-07 01:00:00',
1241 'recipients' => array(),
1242 ),
1243 array(
1244 // On the eve of their 9th birthday, send an email.
1245 'time' => '2014-07-06 20:00:00',
1246 'recipients' => array(array('test-bday@example.com')),
1247 ),
1248 ));
1249 }
1250
1251 public function testContactCustomDateNoAnniv() {
1252 $group = array(
1253 'title' => 'Test_Group',
1254 'name' => 'test_group',
1255 'extends' => array('Individual'),
1256 'style' => 'Inline',
1257 'is_multiple' => FALSE,
1258 'is_active' => 1,
1259 );
1260 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
1261 $field = array(
1262 'label' => 'Graduation',
1263 'data_type' => 'Date',
1264 'html_type' => 'Select Date',
1265 'custom_group_id' => $createGroup['id'],
1266 );
1267 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1268 $contactParams = $this->fixtures['contact'];
1269 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
1270 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
1271 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1272 $actionSchedule = $this->fixtures['sched_contact_grad_tomorrow'];
1273 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1274 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1275 $this->assertTrue(is_numeric($actionScheduleDao->id));
1276 $this->assertCronRuns(array(
1277 array(
1278 // On some random day, no email.
1279 'time' => '2014-03-07 01:00:00',
1280 'recipients' => array(),
1281 ),
1282 array(
1283 // On the eve of their graduation, send an email.
1284 'time' => '2013-12-15 20:00:00',
1285 'recipients' => array(array('test-member@example.com')),
1286 ),
1287 ));
1288 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
1289 }
1290
1291 public function testContactCreatedNoAnniv() {
1292 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1293 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1294 $actionSchedule = $this->fixtures['sched_contact_created_yesterday'];
1295 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1296 $this->assertTrue(is_numeric($actionScheduleDao->id));
1297 $this->assertCronRuns(array(
1298 array(
1299 // On the date created, no email.
1300 'time' => $contact['values'][$contact['id']]['created_date'],
1301 'recipients' => array(),
1302 ),
1303 array(
1304 // The next day, send an email.
1305 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['created_date'] . ' +1 day')),
1306 'recipients' => array(array('test-bday@example.com')),
1307 ),
1308 ));
1309 }
1310
1311 public function testContactModifiedAnniversary() {
1312 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1313 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1314 $modifiedDate = $this->callAPISuccess('Contact', 'getvalue', array('id' => $contact['id'], 'return' => 'modified_date'));
1315 $actionSchedule = $this->fixtures['sched_contact_mod_anniv'];
1316 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1317 $this->assertTrue(is_numeric($actionScheduleDao->id));
1318 $this->assertCronRuns(array(
1319 array(
1320 // On some random day, no email.
1321 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' -60 days')),
1322 'recipients' => array(),
1323 ),
1324 array(
1325 // On the eve of 3 years after they were modified, send an email.
1326 'time' => date('Y-m-d H:i:s', strtotime($modifiedDate . ' +3 years -1 day')),
1327 'recipients' => array(array('test-bday@example.com')),
1328 ),
1329 ));
1330 }
1331
1332 /**
1333 * Check that limit_to + an empty recipients doesn't sent to multiple contacts.
1334 */
1335 public function testMembershipLimitToNone() {
1336 // creates membership with end_date = 20120615
1337 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1338
1339 $this->assertTrue(is_numeric($membership->id));
1340 $result = $this->callAPISuccess('Email', 'create', array(
1341 'contact_id' => $membership->contact_id,
1342 'email' => 'member@example.com',
1343 ));
1344 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1345 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
1346
1347 $this->assertAPISuccess($result);
1348
1349 $actionSchedule = $this->fixtures['sched_membership_end_limit_to_none'];
1350 $actionSchedule['entity_value'] = $membership->membership_type_id;
1351 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1352 $this->assertTrue(is_numeric($actionScheduleDao->id));
1353
1354 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1355 $this->assertCronRuns(array(
1356 array(
1357 // Before the 2-week mark, no email.
1358 'time' => '2012-05-31 01:00:00',
1359 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
1360 'recipients' => array(),
1361 ),
1362 ));
1363 }
1364
1365 public function testMembership_referenceDate() {
1366 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1367
1368 $this->assertTrue(is_numeric($membership->id));
1369 $result = $this->callAPISuccess('Email', 'create', array(
1370 'contact_id' => $membership->contact_id,
1371 'email' => 'member@example.com',
1372 ));
1373
1374 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1375 $this->assertAPISuccess($result);
1376
1377 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1378 $actionSchedule['entity_value'] = $membership->membership_type_id;
1379 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1380 $this->assertTrue(is_numeric($actionScheduleDao->id));
1381
1382 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1383 $this->assertCronRuns(array(
1384 array(
1385 // After the 2-week mark, send an email
1386 'time' => '2012-03-29 01:00:00',
1387 'recipients' => array(array('member@example.com')),
1388 ),
1389 array(
1390 // After the 2-week 1day mark, don't send an email
1391 'time' => '2012-03-30 01:00:00',
1392 'recipients' => array(),
1393 ),
1394 ));
1395
1396 //check if reference date is set to membership's join date
1397 //as per the action_start_date chosen for current schedule reminder
1398 $this->assertEquals('2012-03-15',
1399 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $membership->contact_id, 'reference_date', 'contact_id')
1400 );
1401
1402 //change current membership join date that may signifies as membership renewal activity
1403 $membership->join_date = '2012-03-29';
1404 $membership->save();
1405
1406 $this->assertCronRuns(array(
1407 array(
1408 // After the 13 days of the changed join date 2012-03-29, don't send an email
1409 'time' => '2012-04-11 01:00:00',
1410 'recipients' => array(),
1411 ),
1412 array(
1413 // After the 2-week of the changed join date 2012-03-29, send an email
1414 'time' => '2012-04-12 01:00:00',
1415 'recipients' => array(array('member@example.com')),
1416 ),
1417 ));
1418 $this->assertCronRuns(array(
1419 array(
1420 // It should not re-send on the same day
1421 'time' => '2012-04-12 01:00:00',
1422 'recipients' => array(),
1423 ),
1424 ));
1425 }
1426
1427 public function testMembershipOnMultipleReminder() {
1428 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1429
1430 $this->assertTrue(is_numeric($membership->id));
1431 $result = $this->callAPISuccess('Email', 'create', array(
1432 'contact_id' => $membership->contact_id,
1433 'email' => 'member@example.com',
1434 ));
1435 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1436 $this->assertAPISuccess($result);
1437
1438 $actionScheduleBefore = $this->fixtures['sched_membership_end_2week']; // Send email 2 weeks before end_date
1439 $actionScheduleOn = $this->fixtures['sched_on_membership_end_date']; // Send email on end_date/expiry date
1440 $actionScheduleAfter = $this->fixtures['sched_after_1day_membership_end_date']; // Send email 1 day after end_date/grace period
1441 $actionScheduleBefore['entity_value'] = $actionScheduleOn['entity_value'] = $actionScheduleAfter['entity_value'] = $membership->membership_type_id;
1442 foreach (array('actionScheduleBefore', 'actionScheduleOn', 'actionScheduleAfter') as $value) {
1443 $$value = CRM_Core_BAO_ActionSchedule::add($$value);
1444 $this->assertTrue(is_numeric($$value->id));
1445 }
1446
1447 $this->assertCronRuns(
1448 array(
1449 array(
1450 // 1day 2weeks before membership end date(MED), don't send mail
1451 'time' => '2012-05-31 01:00:00',
1452 'recipients' => array(),
1453 ),
1454 array(
1455 // 2 weeks before MED, send an email
1456 'time' => '2012-06-01 01:00:00',
1457 'recipients' => array(array('member@example.com')),
1458 ),
1459 array(
1460 // 1day before MED, don't send mail
1461 'time' => '2012-06-14 01:00:00',
1462 'recipients' => array(),
1463 ),
1464 array(
1465 // On MED, send an email
1466 'time' => '2012-06-15 00:00:00',
1467 'recipients' => array(array('member@example.com')),
1468 ),
1469 array(
1470 // After 1day of MED, send an email
1471 'time' => '2012-06-16 01:00:00',
1472 'recipients' => array(array('member@example.com')),
1473 ),
1474 array(
1475 // After 1day 1min of MED, don't send an email
1476 'time' => '2012-06-17 00:01:00',
1477 'recipients' => array(),
1478 ),
1479 )
1480 );
1481
1482 // Assert the timestamp as of when the emails of respective three reminders as configured
1483 // 2 weeks before, on and 1 day after MED, are sent
1484 $this->assertApproxEquals(
1485 strtotime('2012-06-01 01:00:00'),
1486 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleBefore->id, 'action_date_time', 'action_schedule_id', TRUE)),
1487 3 // Variation in test execution time.
1488 );
1489 $this->assertApproxEquals(
1490 strtotime('2012-06-15 00:00:00'),
1491 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleOn->id, 'action_date_time', 'action_schedule_id', TRUE)),
1492 3 // Variation in test execution time.
1493 );
1494 $this->assertApproxEquals(
1495 strtotime('2012-06-16 01:00:00'),
1496 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleAfter->id, 'action_date_time', 'action_schedule_id', TRUE)),
1497 3 // Variation in test execution time.
1498 );
1499
1500 //extend MED to 2 weeks after the current MED (that may signifies as membership renewal activity)
1501 // and lets assert as of when the new set of reminders will be sent against their respective Schedule Reminders(SR)
1502 $membership->end_date = '2012-06-20';
1503 $membership->save();
1504
1505 $result = $this->callAPISuccess('Contact', 'get', array('id' => $membership->contact_id));
1506 $this->assertCronRuns(
1507 array(
1508 array(
1509 // 1day 2weeks before membership end date(MED), don't send mail
1510 'time' => '2012-06-05 01:00:00',
1511 'recipients' => array(),
1512 ),
1513 array(
1514 // 2 weeks before MED, send an email
1515 'time' => '2012-06-06 01:00:00',
1516 'recipients' => array(array('member@example.com')),
1517 ),
1518 array(
1519 // 1day before MED, don't send mail
1520 'time' => '2012-06-19 01:00:00',
1521 'recipients' => array(),
1522 ),
1523 array(
1524 // On MED, send an email
1525 'time' => '2012-06-20 00:00:00',
1526 'recipients' => array(array('member@example.com')),
1527 ),
1528 array(
1529 // After 1day of MED, send an email
1530 'time' => '2012-06-21 01:00:00',
1531 'recipients' => array(array('member@example.com')),
1532 ),
1533 array(
1534 // After 1day 1min of MED, don't send an email
1535 'time' => '2012-07-21 00:01:00',
1536 'recipients' => array(),
1537 ),
1538 ));
1539 }
1540
1541 public function testContactCustomDate_Anniv() {
1542 $group = array(
1543 'title' => 'Test_Group now',
1544 'name' => 'test_group_now',
1545 'extends' => array('Individual'),
1546 'style' => 'Inline',
1547 'is_multiple' => FALSE,
1548 'is_active' => 1,
1549 );
1550 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
1551 $field = array(
1552 'label' => 'Graduation',
1553 'data_type' => 'Date',
1554 'html_type' => 'Select Date',
1555 'custom_group_id' => $createGroup['id'],
1556 );
1557 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1558
1559 $contactParams = $this->fixtures['contact'];
1560 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
1561 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
1562 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1563 $actionSchedule = $this->fixtures['sched_contact_grad_anniv'];
1564 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1565 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1566 $this->assertTrue(is_numeric($actionScheduleDao->id));
1567 $this->assertCronRuns(array(
1568 array(
1569 // On some random day, no email.
1570 'time' => '2014-03-07 01:00:00',
1571 'recipients' => array(),
1572 ),
1573 array(
1574 // A week after their 5th anniversary of graduation, send an email.
1575 'time' => '2018-12-23 20:00:00',
1576 'recipients' => array(array('test-member@example.com')),
1577 ),
1578 ));
1579 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
1580 }
1581
1582 public function testEventTypeStartDate() {
1583 // Create event+participant with start_date = 20120315, end_date = 20120615.
1584 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
1585 $this->callAPISuccess('Email', 'create', array(
1586 'contact_id' => $participant->contact_id,
1587 'email' => 'test-event@example.com',
1588 ));
1589 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1590
1591 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
1592 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
1593 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1594
1595 //echo "CREATED\n"; ob_flush(); sleep(20);
1596
1597 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1598 $this->assertCronRuns(array(
1599 array(
1600 // 2 weeks before
1601 'time' => '2012-03-02 01:00:00',
1602 'recipients' => array(),
1603 ),
1604 array(
1605 // 1 week before
1606 'time' => '2012-03-08 01:00:00',
1607 'recipients' => array(array('test-event@example.com')),
1608 ),
1609 array(
1610 // And then nothing else
1611 'time' => '2012-03-16 01:00:00',
1612 'recipients' => array(),
1613 ),
1614 ));
1615 }
1616
1617 public function testEventTypeEndDateRepeat() {
1618 // Create event+participant with start_date = 20120315, end_date = 20120615.
1619 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
1620 $this->callAPISuccess('Email', 'create', array(
1621 'contact_id' => $participant->contact_id,
1622 'email' => 'test-event@example.com',
1623 ));
1624 $c = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1625
1626 $actionSchedule = $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'];
1627 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
1628 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1629
1630 $this->assertCronRuns(array(
1631 array(
1632 // Almost 2 months.
1633 'time' => '2012-08-13 01:00:00',
1634 'recipients' => array(),
1635 ),
1636 array(
1637 // After the 2-month mark, send an email.
1638 'time' => '2012-08-16 01:00:00',
1639 'recipients' => array(array('test-event@example.com')),
1640 ),
1641 array(
1642 // After 2 months and 1 week, don't repeat yet.
1643 'time' => '2012-08-23 02:00:00',
1644 'recipients' => array(),
1645 ),
1646 array(
1647 // After 2 months and 2 weeks
1648 'time' => '2012-08-30 02:00:00',
1649 'recipients' => array(array('test-event@example.com')),
1650 ),
1651 array(
1652 // After 2 months and 4 week
1653 'time' => '2012-09-13 02:00:00',
1654 'recipients' => array(array('test-event@example.com')),
1655 ),
1656 array(
1657 // After 2 months and 6 weeks
1658 'time' => '2012-09-27 01:00:00',
1659 'recipients' => array(),
1660 ),
1661 ));
1662 }
1663
1664 // TODO // function testMembershipEndDate_NonMatch() { }
1665 // TODO // function testEventTypeStartDate_Match() { }
1666 // TODO // function testEventTypeEndDate_Match() { }
1667 // TODO // function testEventNameStartDate_Match() { }
1668 // TODO // function testEventNameEndDate_Match() { }
1669
1670 /**
1671 * Run a series of cron jobs and make an assertion about email deliveries.
1672 *
1673 * @param array $cronRuns
1674 * array specifying when to run cron and what messages to expect; each item is an array with keys:
1675 * - time: string, e.g. '2012-06-15 21:00:01'
1676 * - recipients: array(array(string)), list of email addresses which should receive messages
1677 */
1678 public function assertCronRuns($cronRuns) {
1679 foreach ($cronRuns as $cronRun) {
1680 CRM_Utils_Time::setTime($cronRun['time']);
1681 $this->callAPISuccess('job', 'send_reminder', array());
1682 $this->mut->assertRecipients($cronRun['recipients']);
1683 if (array_key_exists('subjects', $cronRun)) {
1684 $this->mut->assertSubjects($cronRun['subjects']);
1685 }
1686 $this->mut->clearMessages();
1687 }
1688 }
1689
1690 /**
1691 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
1692 */
1693 private $_testObjects;
1694
1695 /**
1696 * Sets up the fixture, for example, opens a network connection.
1697 *
1698 * This method is called before a test is executed.
1699 */
1700 protected function _setUp() {
1701 $this->_testObjects = array();
1702 }
1703
1704 /**
1705 * Tears down the fixture, for example, closes a network connection.
1706 *
1707 * This method is called after a test is executed.
1708 */
1709 protected function _tearDown() {
1710 parent::tearDown();
1711 $this->deleteTestObjects();
1712 }
1713
1714 /**
1715 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
1716 * created entities and provides for brainless cleanup.
1717 *
1718 * @see CRM_Core_DAO::createTestObject
1719 *
1720 * @param $daoName
1721 * @param array $params
1722 * @param int $numObjects
1723 * @param bool $createOnly
1724 *
1725 * @return array|NULL|object
1726 */
1727 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
1728 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
1729 if (is_array($objects)) {
1730 $this->registerTestObjects($objects);
1731 }
1732 else {
1733 $this->registerTestObjects(array($objects));
1734 }
1735 return $objects;
1736 }
1737
1738 /**
1739 * @param array $objects
1740 * DAO or BAO objects.
1741 */
1742 public function registerTestObjects($objects) {
1743 //if (is_object($objects)) {
1744 // $objects = array($objects);
1745 //}
1746 foreach ($objects as $object) {
1747 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
1748 $this->_testObjects[$daoName][] = $object->id;
1749 }
1750 }
1751
1752 public function deleteTestObjects() {
1753 // Note: You might argue that the FK relations between test
1754 // objects could make this problematic; however, it should
1755 // behave intuitively as long as we mentally split our
1756 // test-objects between the "manual/primary records"
1757 // and the "automatic/secondary records"
1758 foreach ($this->_testObjects as $daoName => $daoIds) {
1759 foreach ($daoIds as $daoId) {
1760 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
1761 }
1762 }
1763 $this->_testObjects = array();
1764 }
1765
1766 /**
1767 * Test that the various repetition units work correctly.
1768 * CRM-17028
1769 */
1770 public function testRepetitionFrequencyUnit() {
1771 $membershipTypeParams = array(
1772 'duration_interval' => '1',
1773 'duration_unit' => 'year',
1774 'is_active' => 1,
1775 'period_type' => 'rolling',
1776 );
1777 $membershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipTypeParams);
1778 $interval_units = array('hour', 'day', 'week', 'month', 'year');
1779 foreach ($interval_units as $interval_unit) {
1780 $membershipEndDate = DateTime::createFromFormat('Y-m-d H:i:s', "2013-03-15 00:00:00");
1781 $contactParams = array(
1782 'contact_type' => 'Individual',
1783 'first_name' => 'Test',
1784 'last_name' => "Interval $interval_unit",
1785 'is_deceased' => 0,
1786 );
1787 $contact = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
1788 $this->assertTrue(is_numeric($contact->id));
1789 $emailParams = array(
1790 'contact_id' => $contact->id,
1791 'email' => "test-member-{$interval_unit}@example.com",
1792 'location_type_id' => 1,
1793 );
1794 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
1795 $this->assertTrue(is_numeric($email->id));
1796 $membershipParams = array(
1797 'membership_type_id' => $membershipType->id,
1798 'contact_id' => $contact->id,
1799 'join_date' => '20120315',
1800 'start_date' => '20120315',
1801 'end_date' => '20130315',
1802 'is_override' => 0,
1803 'status_id' => 2,
1804 );
1805 $membershipParams['status-id'] = 1;
1806 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
1807 $actionScheduleParams = $this->fixtures['sched_on_membership_end_date_repeat_interval'];
1808 $actionScheduleParams['entity_value'] = $membershipType->id;
1809 $actionScheduleParams['repetition_frequency_unit'] = $interval_unit;
1810 $actionScheduleParams['repetition_frequency_interval'] = 2;
1811 $actionSchedule = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
1812 $this->assertTrue(is_numeric($actionSchedule->id));
1813 $beforeEndDate = $this->createModifiedDateTime($membershipEndDate, '-1 day');
1814 $beforeFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+1 $interval_unit");
1815 $afterFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+2 $interval_unit");
1816 $cronRuns = array(
1817 array(
1818 'time' => $beforeEndDate->format('Y-m-d H:i:s'),
1819 'recipients' => array(),
1820 ),
1821 array(
1822 'time' => $membershipEndDate->format('Y-m-d H:i:s'),
1823 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
1824 ),
1825 array(
1826 'time' => $beforeFirstUnit->format('Y-m-d H:i:s'),
1827 'recipients' => array(),
1828 ),
1829 array(
1830 'time' => $afterFirstUnit->format('Y-m-d H:i:s'),
1831 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
1832 ),
1833 );
1834 $this->assertCronRuns($cronRuns);
1835 $actionSchedule->delete();
1836 $membership->delete();
1837 }
1838 }
1839
1840 public function createModifiedDateTime($origDateTime, $modifyRule) {
1841 $newDateTime = clone($origDateTime);
1842 $newDateTime->modify($modifyRule);
1843 return $newDateTime;
1844 }
1845
1846 }