dev/core#481 Ensure that Bulk Mailings is a checkbox rather than radio to allow for...
[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/start date,
969 * an email should be sent.
970 */
971 public function testMembershipDateMatch() {
972 foreach (['membership_join_date', 'membership_start_date'] as $date) {
973 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
974 $this->assertTrue(is_numeric($membership->id));
975 $result = $this->callAPISuccess('Email', 'create', array(
976 'contact_id' => $membership->contact_id,
977 'email' => 'test-member@example.com',
978 'location_type_id' => 1,
979 ));
980 $this->assertAPISuccess($result);
981
982 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
983 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
984 $actionSchedule['start_action_date'] = $date;
985 $actionSchedule['entity_value'] = $membership->membership_type_id;
986 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
987 $this->assertTrue(is_numeric($actionScheduleDao->id));
988
989 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
990 $this->assertCronRuns(array(
991 array(
992 // Before the 2-week mark, no email.
993 'time' => '2012-03-28 01:00:00',
994 'recipients' => array(),
995 'subjects' => array(),
996 ),
997 array(
998 // After the 2-week mark, send an email.
999 'time' => '2012-03-29 01:00:00',
1000 'recipients' => array(array('test-member@example.com')),
1001 'subjects' => array('subject sched_membership_join_2week (joined March 15th, 2012)'),
1002 ),
1003 ));
1004 }
1005 }
1006
1007
1008 /**
1009 * CRM-21675: Support parent and smart group in 'Limit to' field
1010 */
1011 public function testScheduleReminderWithParentGroup() {
1012 // Contact A with birth-date at '07-07-2005' and gender - Male, later got added in smart group
1013 $contactID1 = $this->individualCreate(array('birth_date' => '20050707', 'gender_id' => 1, 'email' => 'abc@test.com'));
1014 // Contact B with birth-date at '07-07-2005', later got added in regular group
1015 $contactID2 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'def@test.com'), 1);
1016 // Contact C with birth-date at '07-07-2005', but not included in any group
1017 $contactID3 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'ghi@test.com'), 2);
1018
1019 // create regular group and add Contact B to it
1020 $groupID = $this->groupCreate();
1021 $this->callAPISuccess('GroupContact', 'Create', array(
1022 'group_id' => $groupID,
1023 'contact_id' => $contactID2,
1024 ));
1025
1026 // create smart group which will contain all Male contacts
1027 $smartGroupParams = array('formValues' => array('gender_id' => 1));
1028 $smartGroupID = $this->smartGroupCreate(
1029 $smartGroupParams,
1030 array(
1031 'name' => 'new_smart_group',
1032 'title' => 'New Smart Group',
1033 'parents' => array($groupID => 1),
1034 )
1035 );
1036
1037 $actionScheduleParams = array(
1038 'name' => 'sched_contact_bday_yesterday',
1039 'title' => 'sched_contact_bday_yesterday',
1040 'absolute_date' => '',
1041 'body_html' => '<p>you look like you were born yesterday!</p>',
1042 'body_text' => 'you look like you were born yesterday!',
1043 'end_action' => '',
1044 'end_date' => '',
1045 'end_frequency_interval' => '',
1046 'end_frequency_unit' => '',
1047 'entity_status' => 1,
1048 'entity_value' => 'birth_date',
1049 'limit_to' => 1,
1050 'group_id' => $groupID,
1051 'is_active' => 1,
1052 'is_repeat' => '0',
1053 'mapping_id' => 6,
1054 'msg_template_id' => '',
1055 'recipient' => '2',
1056 'recipient_listing' => '',
1057 'recipient_manual' => '',
1058 'record_activity' => 1,
1059 'repetition_frequency_interval' => '',
1060 'repetition_frequency_unit' => '',
1061 'start_action_condition' => 'after',
1062 'start_action_date' => 'date_field',
1063 'start_action_offset' => '1',
1064 'start_action_unit' => 'day',
1065 'subject' => 'subject sched_contact_bday_yesterday',
1066 );
1067
1068 // Create schedule reminder where parent group ($groupID) is selectd to limit recipients,
1069 // which contain a individual contact - $contactID2 and is parent to smart group.
1070 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
1071 $this->assertTrue(is_numeric($actionScheduleDao->id));
1072 $this->assertCronRuns(array(
1073 array(
1074 // On the birthday, no email.
1075 'time' => '2005-07-07 01:00:00',
1076 'recipients' => array(),
1077 ),
1078 array(
1079 // The next day, send an email.
1080 'time' => '2005-07-08 20:00:00',
1081 'recipients' => array(
1082 array(
1083 'def@test.com',
1084 ),
1085 array(
1086 'abc@test.com',
1087 ),
1088 ),
1089 ),
1090 ));
1091 $this->groupDelete($smartGroupID);
1092 $this->groupDelete($groupID);
1093 }
1094
1095 /**
1096 * Test end date email sent.
1097 *
1098 * For contacts/members which match schedule based on join date,
1099 * an email should be sent.
1100 */
1101 public function testMembershipJoinDateNonMatch() {
1102 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures['rolling_membership']);
1103 $this->assertTrue(is_numeric($membership->id));
1104 $result = $this->callAPISuccess('Email', 'create', array(
1105 'contact_id' => $membership->contact_id,
1106 'location_type_id' => 1,
1107 'email' => 'test-member@example.com',
1108 ));
1109
1110 // Add an alternative membership type, and only send messages for that type
1111 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
1112 $this->assertTrue(is_numeric($extraMembershipType->id));
1113 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_membership_join_2week']);
1114 $this->assertTrue(is_numeric($actionScheduleDao->id));
1115 $actionScheduleDao->entity_value = $extraMembershipType->id;
1116 $actionScheduleDao->save();
1117
1118 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1119 $this->assertCronRuns(array(
1120 array(
1121 // After the 2-week mark, don't send email because we have different membership type.
1122 'time' => '2012-03-29 01:00:00',
1123 'recipients' => array(),
1124 ),
1125 ));
1126 }
1127
1128 /**
1129 * Test that the first and SECOND notifications are sent out.
1130 */
1131 public function testMembershipEndDateRepeat() {
1132 // creates membership with end_date = 20120615
1133 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1134 $result = $this->callAPISuccess('Email', 'create', array(
1135 'contact_id' => $membership->contact_id,
1136 'email' => 'test-member@example.com',
1137 ));
1138 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1139
1140 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1141 $actionSchedule['entity_value'] = $membership->membership_type_id;
1142 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1143
1144 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1145 $this->assertCronRuns(array(
1146 array(
1147 // After the 2-week mark, send an email.
1148 'time' => '2012-08-15 01:00:00',
1149 'recipients' => array(array('test-member@example.com')),
1150 ),
1151 array(
1152 // After the 2-week mark, send an email.
1153 'time' => '2012-09-12 01:00:00',
1154 'recipients' => array(array('test-member@example.com')),
1155 ),
1156 ));
1157 }
1158
1159 /**
1160 * Test behaviour when date changes.
1161 *
1162 * Test that the first notification is sent but the second is NOT sent if the end date changes in
1163 * between
1164 * see CRM-15376
1165 */
1166 public function testMembershipEndDateRepeatChangedEndDate_CRM_15376() {
1167 // creates membership with end_date = 20120615
1168 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1169 $this->callAPISuccess('Email', 'create', array(
1170 'contact_id' => $membership->contact_id,
1171 'email' => 'test-member@example.com',
1172 ));
1173 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1174
1175 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1176 $actionSchedule['entity_value'] = $membership->membership_type_id;
1177 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1178 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1179 $this->assertCronRuns(array(
1180 array(
1181 // After the 2-week mark, send an email.
1182 'time' => '2012-08-15 01:00:00',
1183 'recipients' => array(array('test-member@example.com')),
1184 ),
1185 ));
1186
1187 // Extend membership - reminder should NOT go out.
1188 $this->callAPISuccess('membership', 'create', array('id' => $membership->id, 'end_date' => '2014-01-01'));
1189 $this->assertCronRuns(array(
1190 array(
1191 // After the 2-week mark, send an email.
1192 'time' => '2012-09-12 01:00:00',
1193 'recipients' => array(),
1194 ),
1195 ));
1196 }
1197
1198 /**
1199 * Test membership end date email sends.
1200 *
1201 * For contacts/members which match schedule based on end date,
1202 * an email should be sent.
1203 */
1204 public function testMembershipEndDateMatch() {
1205 // creates membership with end_date = 20120615
1206 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1207 $this->assertTrue(is_numeric($membership->id));
1208 $this->callAPISuccess('Email', 'create', array(
1209 'contact_id' => $membership->contact_id,
1210 'email' => 'test-member@example.com',
1211 ));
1212 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1213
1214 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
1215 $actionSchedule['entity_value'] = $membership->membership_type_id;
1216 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1217 $this->assertTrue(is_numeric($actionScheduleDao->id));
1218
1219 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1220 $this->assertCronRuns(array(
1221 array(
1222 // Before the 2-week mark, no email.
1223 'time' => '2012-05-31 01:00:00',
1224 // 'time' => '2012-06-01 01:00:00',
1225 // FIXME: Is this the right boundary?
1226 'recipients' => array(),
1227 ),
1228 array(
1229 // After the 2-week mark, send an email.
1230 'time' => '2012-06-01 01:00:00',
1231 'recipients' => array(array('test-member@example.com')),
1232 ),
1233 ));
1234
1235 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
1236 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
1237 $membership->end_date = '2012-09-15';
1238 $membership->save();
1239
1240 //change the email id of chosen membership contact to assert
1241 //recipient of not the previously sent mail but the new one
1242 $result = $this->callAPISuccess('Email', 'create', array(
1243 'is_primary' => 1,
1244 'contact_id' => $membership->contact_id,
1245 'email' => 'member2@example.com',
1246 ));
1247 $this->assertAPISuccess($result);
1248
1249 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
1250 $this->assertCronRuns(array(
1251 array(
1252 // Before the 2-week mark, no email
1253 'time' => '2012-08-31 01:00:00',
1254 'recipients' => array(),
1255 ),
1256 //array( // After the 2-week mark, send an email
1257 //'time' => '2012-09-01 01:00:00',
1258 //'recipients' => array(array('member2@example.com')),
1259 //),
1260 ));
1261 }
1262
1263
1264 /**
1265 * Test membership end date email.
1266 *
1267 * For contacts/members which match schedule based on end date,
1268 * an email should be sent.
1269 */
1270 public function testMembershipEndDateNoMatch() {
1271 // creates membership with end_date = 20120615
1272 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 3)));
1273 $this->assertTrue(is_numeric($membership->id));
1274 $result = $this->callAPISuccess('Email', 'create', array(
1275 'contact_id' => $membership->contact_id,
1276 'email' => 'test-member@example.com',
1277 ));
1278 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1279
1280 $actionSchedule = $this->fixtures['sched_membership_end_2month'];
1281 $actionSchedule['entity_value'] = $membership->membership_type_id;
1282 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1283 $this->assertTrue(is_numeric($actionScheduleDao->id));
1284
1285 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1286 $this->assertCronRuns(array(
1287 array(
1288 // Before the 2-week mark, no email.
1289 'time' => '2012-05-31 01:00:00',
1290 // 'time' => '2012-06-01 01:00:00',
1291 // FIXME: Is this the right boundary?
1292 'recipients' => array(),
1293 ),
1294 array(
1295 // After the 2-week mark, send an email.
1296 'time' => '2013-05-01 01:00:00',
1297 'recipients' => array(),
1298 ),
1299 ));
1300 }
1301
1302 public function testContactBirthDateNoAnniv() {
1303 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1304 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1305 $actionSchedule = $this->fixtures['sched_contact_bday_yesterday'];
1306 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1307 $this->assertTrue(is_numeric($actionScheduleDao->id));
1308 $this->assertCronRuns(array(
1309 array(
1310 // On the birthday, no email.
1311 'time' => '2005-07-07 01:00:00',
1312 'recipients' => array(),
1313 ),
1314 array(
1315 // The next day, send an email.
1316 'time' => '2005-07-08 20:00:00',
1317 'recipients' => array(array('test-bday@example.com')),
1318 ),
1319 ));
1320 }
1321
1322 public function testContactBirthDateAnniversary() {
1323 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1324 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1325 $actionSchedule = $this->fixtures['sched_contact_bday_anniv'];
1326 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1327 $this->assertTrue(is_numeric($actionScheduleDao->id));
1328 $this->assertCronRuns(array(
1329 array(
1330 // On some random day, no email.
1331 'time' => '2014-03-07 01:00:00',
1332 'recipients' => array(),
1333 ),
1334 array(
1335 // On the eve of their 9th birthday, send an email.
1336 'time' => '2014-07-06 20:00:00',
1337 'recipients' => array(array('test-bday@example.com')),
1338 ),
1339 ));
1340 }
1341
1342 public function testContactCustomDateNoAnniv() {
1343 $group = array(
1344 'title' => 'Test_Group',
1345 'name' => 'test_group',
1346 'extends' => array('Individual'),
1347 'style' => 'Inline',
1348 'is_multiple' => FALSE,
1349 'is_active' => 1,
1350 );
1351 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
1352 $field = array(
1353 'label' => 'Graduation',
1354 'data_type' => 'Date',
1355 'html_type' => 'Select Date',
1356 'custom_group_id' => $createGroup['id'],
1357 );
1358 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1359 $contactParams = $this->fixtures['contact'];
1360 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
1361 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
1362 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1363 $actionSchedule = $this->fixtures['sched_contact_grad_tomorrow'];
1364 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1365 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1366 $this->assertTrue(is_numeric($actionScheduleDao->id));
1367 $this->assertCronRuns(array(
1368 array(
1369 // On some random day, no email.
1370 'time' => '2014-03-07 01:00:00',
1371 'recipients' => array(),
1372 ),
1373 array(
1374 // On the eve of their graduation, send an email.
1375 'time' => '2013-12-15 20:00:00',
1376 'recipients' => array(array('test-member@example.com')),
1377 ),
1378 ));
1379 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
1380 }
1381
1382 public function testContactCreatedNoAnniv() {
1383 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1384 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1385 $actionSchedule = $this->fixtures['sched_contact_created_yesterday'];
1386 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1387 $this->assertTrue(is_numeric($actionScheduleDao->id));
1388 $this->assertCronRuns(array(
1389 array(
1390 // On the date created, no email.
1391 'time' => $contact['values'][$contact['id']]['created_date'],
1392 'recipients' => array(),
1393 ),
1394 array(
1395 // The next day, send an email.
1396 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['created_date'] . ' +1 day')),
1397 'recipients' => array(array('test-bday@example.com')),
1398 ),
1399 ));
1400 }
1401
1402 public function testContactModifiedAnniversary() {
1403 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1404 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1405 $modifiedDate = $this->callAPISuccess('Contact', 'getvalue', array('id' => $contact['id'], 'return' => 'modified_date'));
1406 $actionSchedule = $this->fixtures['sched_contact_mod_anniv'];
1407 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1408 $this->assertTrue(is_numeric($actionScheduleDao->id));
1409 $this->assertCronRuns(array(
1410 array(
1411 // On some random day, no email.
1412 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' -60 days')),
1413 'recipients' => array(),
1414 ),
1415 array(
1416 // On the eve of 3 years after they were modified, send an email.
1417 'time' => date('Y-m-d H:i:s', strtotime($modifiedDate . ' +3 years -1 day')),
1418 'recipients' => array(array('test-bday@example.com')),
1419 ),
1420 ));
1421 }
1422
1423 /**
1424 * Check that limit_to + an empty recipients doesn't sent to multiple contacts.
1425 */
1426 public function testMembershipLimitToNone() {
1427 // creates membership with end_date = 20120615
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 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1436 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
1437
1438 $this->assertAPISuccess($result);
1439
1440 $actionSchedule = $this->fixtures['sched_membership_end_limit_to_none'];
1441 $actionSchedule['entity_value'] = $membership->membership_type_id;
1442 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1443 $this->assertTrue(is_numeric($actionScheduleDao->id));
1444
1445 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1446 $this->assertCronRuns(array(
1447 array(
1448 // Before the 2-week mark, no email.
1449 'time' => '2012-05-31 01:00:00',
1450 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
1451 'recipients' => array(),
1452 ),
1453 ));
1454 }
1455
1456 public function testMembership_referenceDate() {
1457 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1458
1459 $this->assertTrue(is_numeric($membership->id));
1460 $result = $this->callAPISuccess('Email', 'create', array(
1461 'contact_id' => $membership->contact_id,
1462 'email' => 'member@example.com',
1463 ));
1464
1465 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1466 $this->assertAPISuccess($result);
1467
1468 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1469 $actionSchedule['entity_value'] = $membership->membership_type_id;
1470 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1471 $this->assertTrue(is_numeric($actionScheduleDao->id));
1472
1473 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1474 $this->assertCronRuns(array(
1475 array(
1476 // After the 2-week mark, send an email
1477 'time' => '2012-03-29 01:00:00',
1478 'recipients' => array(array('member@example.com')),
1479 ),
1480 array(
1481 // After the 2-week 1day mark, don't send an email
1482 'time' => '2012-03-30 01:00:00',
1483 'recipients' => array(),
1484 ),
1485 ));
1486
1487 //check if reference date is set to membership's join date
1488 //as per the action_start_date chosen for current schedule reminder
1489 $this->assertEquals('2012-03-15',
1490 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $membership->contact_id, 'reference_date', 'contact_id')
1491 );
1492
1493 //change current membership join date that may signifies as membership renewal activity
1494 $membership->join_date = '2012-03-29';
1495 $membership->save();
1496
1497 $this->assertCronRuns(array(
1498 array(
1499 // After the 13 days of the changed join date 2012-03-29, don't send an email
1500 'time' => '2012-04-11 01:00:00',
1501 'recipients' => array(),
1502 ),
1503 array(
1504 // After the 2-week of the changed join date 2012-03-29, send an email
1505 'time' => '2012-04-12 01:00:00',
1506 'recipients' => array(array('member@example.com')),
1507 ),
1508 ));
1509 $this->assertCronRuns(array(
1510 array(
1511 // It should not re-send on the same day
1512 'time' => '2012-04-12 01:00:00',
1513 'recipients' => array(),
1514 ),
1515 ));
1516 }
1517
1518 public function testMembershipOnMultipleReminder() {
1519 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1520
1521 $this->assertTrue(is_numeric($membership->id));
1522 $result = $this->callAPISuccess('Email', 'create', array(
1523 'contact_id' => $membership->contact_id,
1524 'email' => 'member@example.com',
1525 ));
1526 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1527 $this->assertAPISuccess($result);
1528
1529 $actionScheduleBefore = $this->fixtures['sched_membership_end_2week']; // Send email 2 weeks before end_date
1530 $actionScheduleOn = $this->fixtures['sched_on_membership_end_date']; // Send email on end_date/expiry date
1531 $actionScheduleAfter = $this->fixtures['sched_after_1day_membership_end_date']; // Send email 1 day after end_date/grace period
1532 $actionScheduleBefore['entity_value'] = $actionScheduleOn['entity_value'] = $actionScheduleAfter['entity_value'] = $membership->membership_type_id;
1533 foreach (array('actionScheduleBefore', 'actionScheduleOn', 'actionScheduleAfter') as $value) {
1534 $$value = CRM_Core_BAO_ActionSchedule::add($$value);
1535 $this->assertTrue(is_numeric($$value->id));
1536 }
1537
1538 $this->assertCronRuns(
1539 array(
1540 array(
1541 // 1day 2weeks before membership end date(MED), don't send mail
1542 'time' => '2012-05-31 01:00:00',
1543 'recipients' => array(),
1544 ),
1545 array(
1546 // 2 weeks before MED, send an email
1547 'time' => '2012-06-01 01:00:00',
1548 'recipients' => array(array('member@example.com')),
1549 ),
1550 array(
1551 // 1day before MED, don't send mail
1552 'time' => '2012-06-14 01:00:00',
1553 'recipients' => array(),
1554 ),
1555 array(
1556 // On MED, send an email
1557 'time' => '2012-06-15 00:00:00',
1558 'recipients' => array(array('member@example.com')),
1559 ),
1560 array(
1561 // After 1day of MED, send an email
1562 'time' => '2012-06-16 01:00:00',
1563 'recipients' => array(array('member@example.com')),
1564 ),
1565 array(
1566 // After 1day 1min of MED, don't send an email
1567 'time' => '2012-06-17 00:01:00',
1568 'recipients' => array(),
1569 ),
1570 )
1571 );
1572
1573 // Assert the timestamp as of when the emails of respective three reminders as configured
1574 // 2 weeks before, on and 1 day after MED, are sent
1575 $this->assertApproxEquals(
1576 strtotime('2012-06-01 01:00:00'),
1577 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleBefore->id, 'action_date_time', 'action_schedule_id', TRUE)),
1578 3 // Variation in test execution time.
1579 );
1580 $this->assertApproxEquals(
1581 strtotime('2012-06-15 00:00:00'),
1582 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleOn->id, 'action_date_time', 'action_schedule_id', TRUE)),
1583 3 // Variation in test execution time.
1584 );
1585 $this->assertApproxEquals(
1586 strtotime('2012-06-16 01:00:00'),
1587 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleAfter->id, 'action_date_time', 'action_schedule_id', TRUE)),
1588 3 // Variation in test execution time.
1589 );
1590
1591 //extend MED to 2 weeks after the current MED (that may signifies as membership renewal activity)
1592 // and lets assert as of when the new set of reminders will be sent against their respective Schedule Reminders(SR)
1593 $membership->end_date = '2012-06-20';
1594 $membership->save();
1595
1596 $result = $this->callAPISuccess('Contact', 'get', array('id' => $membership->contact_id));
1597 $this->assertCronRuns(
1598 array(
1599 array(
1600 // 1day 2weeks before membership end date(MED), don't send mail
1601 'time' => '2012-06-05 01:00:00',
1602 'recipients' => array(),
1603 ),
1604 array(
1605 // 2 weeks before MED, send an email
1606 'time' => '2012-06-06 01:00:00',
1607 'recipients' => array(array('member@example.com')),
1608 ),
1609 array(
1610 // 1day before MED, don't send mail
1611 'time' => '2012-06-19 01:00:00',
1612 'recipients' => array(),
1613 ),
1614 array(
1615 // On MED, send an email
1616 'time' => '2012-06-20 00:00:00',
1617 'recipients' => array(array('member@example.com')),
1618 ),
1619 array(
1620 // After 1day of MED, send an email
1621 'time' => '2012-06-21 01:00:00',
1622 'recipients' => array(array('member@example.com')),
1623 ),
1624 array(
1625 // After 1day 1min of MED, don't send an email
1626 'time' => '2012-07-21 00:01:00',
1627 'recipients' => array(),
1628 ),
1629 ));
1630 }
1631
1632 public function testContactCustomDate_Anniv() {
1633 $group = array(
1634 'title' => 'Test_Group now',
1635 'name' => 'test_group_now',
1636 'extends' => array('Individual'),
1637 'style' => 'Inline',
1638 'is_multiple' => FALSE,
1639 'is_active' => 1,
1640 );
1641 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
1642 $field = array(
1643 'label' => 'Graduation',
1644 'data_type' => 'Date',
1645 'html_type' => 'Select Date',
1646 'custom_group_id' => $createGroup['id'],
1647 );
1648 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1649
1650 $contactParams = $this->fixtures['contact'];
1651 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
1652 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
1653 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1654 $actionSchedule = $this->fixtures['sched_contact_grad_anniv'];
1655 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1656 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1657 $this->assertTrue(is_numeric($actionScheduleDao->id));
1658 $this->assertCronRuns(array(
1659 array(
1660 // On some random day, no email.
1661 'time' => '2014-03-07 01:00:00',
1662 'recipients' => array(),
1663 ),
1664 array(
1665 // A week after their 5th anniversary of graduation, send an email.
1666 'time' => '2018-12-23 20:00:00',
1667 'recipients' => array(array('test-member@example.com')),
1668 ),
1669 ));
1670 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
1671 }
1672
1673 /**
1674 * Test sched reminder set via registration date.
1675 */
1676 public function testEventTypeRegistrationDate() {
1677 //Create contact
1678 $contactParams = array(
1679 'email' => 'test-event@example.com',
1680 );
1681 $contact = $this->individualCreate($contactParams);
1682 //Add it as a participant to an event ending registration - 7 days from now.
1683 $params = array(
1684 'start_date' => date('Ymd', strtotime('-5 day')),
1685 'end_date' => date('Ymd', strtotime('+7 day')),
1686 'registration_start_date' => date('Ymd', strtotime('-5 day')),
1687 'registration_end_date' => date('Ymd', strtotime('+7 day')),
1688 );
1689 $event = $this->eventCreate($params);
1690 $this->participantCreate(array('contact_id' => $contact, 'event_id' => $event['id']));
1691
1692 //Create a scheduled reminder to send email 7 days before registration date.
1693 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
1694 $actionSchedule['start_action_offset'] = 7;
1695 $actionSchedule['start_action_unit'] = 'day';
1696 $actionSchedule['start_action_date'] = 'registration_end_date';
1697 $actionSchedule['entity_value'] = $event['values'][$event['id']]['event_type_id'];
1698 $actionSchedule['entity_status'] = $this->callAPISuccessGetValue('ParticipantStatusType', array(
1699 'return' => "id",
1700 'name' => "Attended",
1701 ));
1702 $actionSched = $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1703 //Run the cron and verify if an email was sent.
1704 $this->assertCronRuns(array(
1705 array(
1706 'time' => date('Y-m-d'),
1707 'recipients' => array(array('test-event@example.com')),
1708 ),
1709 ));
1710
1711 //Create contact 2
1712 $contactParams = array(
1713 'email' => 'test-event2@example.com',
1714 );
1715 $contact2 = $this->individualCreate($contactParams);
1716 //Create an event with registration end date = 2 week from now.
1717 $params['end_date'] = date('Ymd', strtotime('+2 week'));
1718 $params['registration_end_date'] = date('Ymd', strtotime('+2 week'));
1719 $event2 = $this->eventCreate($params);
1720 $this->participantCreate(array('contact_id' => $contact2, 'event_id' => $event2['id']));
1721
1722 //Assert there is no reminder sent to the contact.
1723 $this->assertCronRuns(array(
1724 array(
1725 'time' => date('Y-m-d'),
1726 'recipients' => array(),
1727 ),
1728 ));
1729
1730 //Modify the sched reminder to be sent 2 week from registration end date.
1731 $this->callAPISuccess('action_schedule', 'create', array(
1732 'id' => $actionSched['id'],
1733 'start_action_offset' => 2,
1734 'start_action_unit' => 'week',
1735 ));
1736
1737 //Contact should receive the reminder now.
1738 $this->assertCronRuns(array(
1739 array(
1740 'time' => date('Y-m-d'),
1741 'recipients' => array(array('test-event2@example.com')),
1742 ),
1743 ));
1744 }
1745
1746 /**
1747 * Test sched reminder set via start date.
1748 */
1749 public function testEventTypeStartDate() {
1750 // Create event+participant with start_date = 20120315, end_date = 20120615.
1751 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
1752 $this->callAPISuccess('Email', 'create', array(
1753 'contact_id' => $participant->contact_id,
1754 'email' => 'test-event@example.com',
1755 ));
1756 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1757
1758 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
1759 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
1760 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1761
1762 //echo "CREATED\n"; ob_flush(); sleep(20);
1763
1764 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1765 $this->assertCronRuns(array(
1766 array(
1767 // 2 weeks before
1768 'time' => '2012-03-02 01:00:00',
1769 'recipients' => array(),
1770 ),
1771 array(
1772 // 1 week before
1773 'time' => '2012-03-08 01:00:00',
1774 'recipients' => array(array('test-event@example.com')),
1775 ),
1776 array(
1777 // And then nothing else
1778 'time' => '2012-03-16 01:00:00',
1779 'recipients' => array(),
1780 ),
1781 ));
1782 }
1783
1784 public function testEventTypeEndDateRepeat() {
1785 // Create event+participant with start_date = 20120315, end_date = 20120615.
1786 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
1787 $this->callAPISuccess('Email', 'create', array(
1788 'contact_id' => $participant->contact_id,
1789 'email' => 'test-event@example.com',
1790 ));
1791 $c = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1792
1793 $actionSchedule = $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'];
1794 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
1795 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1796
1797 $this->assertCronRuns(array(
1798 array(
1799 // Almost 2 months.
1800 'time' => '2012-08-13 01:00:00',
1801 'recipients' => array(),
1802 ),
1803 array(
1804 // After the 2-month mark, send an email.
1805 'time' => '2012-08-16 01:00:00',
1806 'recipients' => array(array('test-event@example.com')),
1807 ),
1808 array(
1809 // After 2 months and 1 week, don't repeat yet.
1810 'time' => '2012-08-23 02:00:00',
1811 'recipients' => array(),
1812 ),
1813 array(
1814 // After 2 months and 2 weeks
1815 'time' => '2012-08-30 02:00:00',
1816 'recipients' => array(array('test-event@example.com')),
1817 ),
1818 array(
1819 // After 2 months and 4 week
1820 'time' => '2012-09-13 02:00:00',
1821 'recipients' => array(array('test-event@example.com')),
1822 ),
1823 array(
1824 // After 2 months and 6 weeks
1825 'time' => '2012-09-27 01:00:00',
1826 'recipients' => array(),
1827 ),
1828 ));
1829 }
1830
1831 // TODO // function testMembershipEndDate_NonMatch() { }
1832 // TODO // function testEventTypeStartDate_Match() { }
1833 // TODO // function testEventTypeEndDate_Match() { }
1834 // TODO // function testEventNameStartDate_Match() { }
1835 // TODO // function testEventNameEndDate_Match() { }
1836
1837 /**
1838 * Run a series of cron jobs and make an assertion about email deliveries.
1839 *
1840 * @param array $cronRuns
1841 * array specifying when to run cron and what messages to expect; each item is an array with keys:
1842 * - time: string, e.g. '2012-06-15 21:00:01'
1843 * - recipients: array(array(string)), list of email addresses which should receive messages
1844 */
1845 public function assertCronRuns($cronRuns) {
1846 foreach ($cronRuns as $cronRun) {
1847 CRM_Utils_Time::setTime($cronRun['time']);
1848 $this->callAPISuccess('job', 'send_reminder', array());
1849 $this->mut->assertRecipients($cronRun['recipients']);
1850 if (array_key_exists('subjects', $cronRun)) {
1851 $this->mut->assertSubjects($cronRun['subjects']);
1852 }
1853 $this->mut->clearMessages();
1854 }
1855 }
1856
1857 /**
1858 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
1859 */
1860 private $_testObjects;
1861
1862 /**
1863 * Sets up the fixture, for example, opens a network connection.
1864 *
1865 * This method is called before a test is executed.
1866 */
1867 protected function _setUp() {
1868 $this->_testObjects = array();
1869 }
1870
1871 /**
1872 * Tears down the fixture, for example, closes a network connection.
1873 *
1874 * This method is called after a test is executed.
1875 */
1876 protected function _tearDown() {
1877 parent::tearDown();
1878 $this->deleteTestObjects();
1879 }
1880
1881 /**
1882 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
1883 * created entities and provides for brainless cleanup.
1884 *
1885 * @see CRM_Core_DAO::createTestObject
1886 *
1887 * @param $daoName
1888 * @param array $params
1889 * @param int $numObjects
1890 * @param bool $createOnly
1891 *
1892 * @return array|NULL|object
1893 */
1894 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
1895 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
1896 if (is_array($objects)) {
1897 $this->registerTestObjects($objects);
1898 }
1899 else {
1900 $this->registerTestObjects(array($objects));
1901 }
1902 return $objects;
1903 }
1904
1905 /**
1906 * @param array $objects
1907 * DAO or BAO objects.
1908 */
1909 public function registerTestObjects($objects) {
1910 //if (is_object($objects)) {
1911 // $objects = array($objects);
1912 //}
1913 foreach ($objects as $object) {
1914 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
1915 $this->_testObjects[$daoName][] = $object->id;
1916 }
1917 }
1918
1919 public function deleteTestObjects() {
1920 // Note: You might argue that the FK relations between test
1921 // objects could make this problematic; however, it should
1922 // behave intuitively as long as we mentally split our
1923 // test-objects between the "manual/primary records"
1924 // and the "automatic/secondary records"
1925 foreach ($this->_testObjects as $daoName => $daoIds) {
1926 foreach ($daoIds as $daoId) {
1927 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
1928 }
1929 }
1930 $this->_testObjects = array();
1931 }
1932
1933 /**
1934 * Test that the various repetition units work correctly.
1935 * CRM-17028
1936 */
1937 public function testRepetitionFrequencyUnit() {
1938 $membershipTypeParams = array(
1939 'duration_interval' => '1',
1940 'duration_unit' => 'year',
1941 'is_active' => 1,
1942 'period_type' => 'rolling',
1943 );
1944 $membershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipTypeParams);
1945 $interval_units = array('hour', 'day', 'week', 'month', 'year');
1946 foreach ($interval_units as $interval_unit) {
1947 $membershipEndDate = DateTime::createFromFormat('Y-m-d H:i:s', "2013-03-15 00:00:00");
1948 $contactParams = array(
1949 'contact_type' => 'Individual',
1950 'first_name' => 'Test',
1951 'last_name' => "Interval $interval_unit",
1952 'is_deceased' => 0,
1953 );
1954 $contact = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
1955 $this->assertTrue(is_numeric($contact->id));
1956 $emailParams = array(
1957 'contact_id' => $contact->id,
1958 'is_primary' => 1,
1959 'email' => "test-member-{$interval_unit}@example.com",
1960 'location_type_id' => 1,
1961 );
1962 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
1963 $this->assertTrue(is_numeric($email->id));
1964 $membershipParams = array(
1965 'membership_type_id' => $membershipType->id,
1966 'contact_id' => $contact->id,
1967 'join_date' => '20120315',
1968 'start_date' => '20120315',
1969 'end_date' => '20130315',
1970 'is_override' => 0,
1971 'status_id' => 2,
1972 );
1973 $membershipParams['status-id'] = 1;
1974 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
1975 $actionScheduleParams = $this->fixtures['sched_on_membership_end_date_repeat_interval'];
1976 $actionScheduleParams['entity_value'] = $membershipType->id;
1977 $actionScheduleParams['repetition_frequency_unit'] = $interval_unit;
1978 $actionScheduleParams['repetition_frequency_interval'] = 2;
1979 $actionSchedule = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
1980 $this->assertTrue(is_numeric($actionSchedule->id));
1981 $beforeEndDate = $this->createModifiedDateTime($membershipEndDate, '-1 day');
1982 $beforeFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+1 $interval_unit");
1983 $afterFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+2 $interval_unit");
1984 $cronRuns = array(
1985 array(
1986 'time' => $beforeEndDate->format('Y-m-d H:i:s'),
1987 'recipients' => array(),
1988 ),
1989 array(
1990 'time' => $membershipEndDate->format('Y-m-d H:i:s'),
1991 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
1992 ),
1993 array(
1994 'time' => $beforeFirstUnit->format('Y-m-d H:i:s'),
1995 'recipients' => array(),
1996 ),
1997 array(
1998 'time' => $afterFirstUnit->format('Y-m-d H:i:s'),
1999 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2000 ),
2001 );
2002 $this->assertCronRuns($cronRuns);
2003 $actionSchedule->delete();
2004 $membership->delete();
2005 }
2006 }
2007
2008 public function createModifiedDateTime($origDateTime, $modifyRule) {
2009 $newDateTime = clone($origDateTime);
2010 $newDateTime->modify($modifyRule);
2011 return $newDateTime;
2012 }
2013
2014 }