3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * Class CRM_Core_BAO_ActionScheduleTest
30 * @group ActionSchedule
33 * There are additional tests for some specific entities in other classes:
34 * @see CRM_Activity_ActionMappingTest
35 * @see CRM_Contribute_ActionMapping_ByTypeTest
37 class CRM_Core_BAO_ActionScheduleTest
extends CiviUnitTestCase
{
44 public function setUp() {
47 $this->mut
= new CiviMailUtils($this, TRUE);
49 $this->fixtures
['rolling_membership'] = array(
50 'membership_type_id' => array(
51 'period_type' => 'rolling',
52 'duration_unit' => 'month',
53 'duration_interval' => '3',
56 'join_date' => '20120315',
57 'start_date' => '20120315',
58 'end_date' => '20120615',
62 $this->fixtures
['rolling_membership_past'] = array(
63 'membership_type_id' => array(
64 'period_type' => 'rolling',
65 'duration_unit' => 'month',
66 'duration_interval' => '3',
69 'join_date' => '20100310',
70 'start_date' => '20100310',
71 'end_date' => '20100610',
72 'is_override' => 'NULL',
74 $this->fixtures
['participant'] = array(
78 'title' => 'Example Event',
79 'start_date' => '20120315',
80 'end_date' => '20120615',
88 $this->fixtures
['phonecall'] = array(
90 'activity_type_id' => 2,
91 'activity_date_time' => '20120615100000',
92 'is_current_revision' => 1,
95 $this->fixtures
['contact'] = array(
97 'contact_type' => 'Individual',
98 'email' => 'test-member@example.com',
99 'gender_id' => 'Female',
100 'first_name' => 'Churmondleia',
101 'last_name' => 'Ōtākou',
103 $this->fixtures
['contact_birthdate'] = array(
105 'contact_type' => 'Individual',
106 'email' => 'test-bday@example.com',
107 'birth_date' => '20050707',
109 $this->fixtures
['sched_activity_1day'] = array(
110 'name' => 'One_Day_Phone_Call_Notice',
111 'title' => 'One Day Phone Call Notice',
113 'absolute_date' => NULL,
114 'body_html' => '<p>1-Day (non-repeating) (for {activity.subject})</p>',
115 'body_text' => '1-Day (non-repeating) (for {activity.subject})',
116 'end_action' => NULL,
118 'end_frequency_interval' => NULL,
119 'end_frequency_unit' => NULL,
120 'entity_status' => '1',
121 'entity_value' => '2',
126 'msg_template_id' => NULL,
128 'recipient_listing' => NULL,
129 'recipient_manual' => NULL,
130 'record_activity' => 1,
131 'repetition_frequency_interval' => NULL,
132 'repetition_frequency_unit' => NULL,
133 'start_action_condition' => 'before',
134 'start_action_date' => 'activity_date_time',
135 'start_action_offset' => '1',
136 'start_action_unit' => 'day',
137 'subject' => '1-Day (non-repeating) (about {activity.activity_type})',
139 $this->fixtures
['sched_activity_1day_r'] = array(
140 'name' => 'One_Day_Phone_Call_Notice_R',
141 'title' => 'One Day Phone Call Notice R',
143 'absolute_date' => NULL,
144 'body_html' => '<p>1-Day (repeating)</p>',
145 'body_text' => '1-Day (repeating)',
146 'end_action' => 'after',
147 'end_date' => 'activity_date_time',
148 'end_frequency_interval' => '2',
149 'end_frequency_unit' => 'day',
150 'entity_status' => '1',
151 'entity_value' => '2',
156 'msg_template_id' => NULL,
158 'recipient_listing' => NULL,
159 'recipient_manual' => NULL,
160 'record_activity' => NULL,
161 'repetition_frequency_interval' => '6',
162 'repetition_frequency_unit' => 'hour',
163 'start_action_condition' => 'before',
164 'start_action_date' => 'activity_date_time',
165 'start_action_offset' => '1',
166 'start_action_unit' => 'day',
167 'subject' => '1-Day (repeating) (about {activity.activity_type})',
169 $this->fixtures
['sched_activity_1day_r_on_abs_date'] = array(
170 'name' => 'One_Day_Phone_Call_Notice_R',
171 'title' => 'One Day Phone Call Notice R',
173 'absolute_date' => CRM_Utils_Date
::processDate('20120614100000'),
174 'body_html' => '<p>1-Day (repeating)</p>',
175 'body_text' => '1-Day (repeating)',
176 'entity_status' => '1',
177 'entity_value' => '2',
182 'msg_template_id' => NULL,
184 'recipient_listing' => NULL,
185 'recipient_manual' => NULL,
186 'record_activity' => NULL,
187 'repetition_frequency_interval' => '6',
188 'repetition_frequency_unit' => 'hour',
189 'end_action' => 'after',
190 'end_date' => 'activity_date_time',
191 'end_frequency_interval' => '2',
192 'end_frequency_unit' => 'day',
193 'start_action_condition' => '',
194 'start_action_date' => '',
195 'start_action_offset' => '',
196 'start_action_unit' => '',
197 'subject' => '1-Day (repeating) (about {activity.activity_type})',
199 $this->fixtures
['sched_membership_join_2week'] = array(
200 'name' => 'sched_membership_join_2week',
201 'title' => 'sched_membership_join_2week',
202 'absolute_date' => '',
203 'body_html' => '<p>body sched_membership_join_2week</p>',
204 'body_text' => 'body sched_membership_join_2week',
207 'end_frequency_interval' => '',
208 'end_frequency_unit' => '',
209 'entity_status' => '',
210 'entity_value' => '',
215 'msg_template_id' => '',
217 'recipient_listing' => '',
218 'recipient_manual' => '',
219 'record_activity' => 1,
220 'repetition_frequency_interval' => '',
221 'repetition_frequency_unit' => '',
222 'start_action_condition' => 'after',
223 'start_action_date' => 'membership_join_date',
224 'start_action_offset' => '2',
225 'start_action_unit' => 'week',
226 'subject' => 'subject sched_membership_join_2week (joined {membership.join_date})',
228 $this->fixtures
['sched_membership_start_1week'] = array(
229 'name' => 'sched_membership_start_1week',
230 'title' => 'sched_membership_start_1week',
231 'absolute_date' => '',
232 'body_html' => '<p>body sched_membership_start_1week</p>',
233 'body_text' => 'body sched_membership_start_1week',
236 'end_frequency_interval' => '',
237 'end_frequency_unit' => '',
238 'entity_status' => '',
239 'entity_value' => '',
244 'msg_template_id' => '',
246 'recipient_listing' => '',
247 'recipient_manual' => '',
248 'record_activity' => 1,
249 'repetition_frequency_interval' => '',
250 'repetition_frequency_unit' => '',
251 'start_action_condition' => 'after',
252 'start_action_date' => 'membership_start_date',
253 'start_action_offset' => '1',
254 'start_action_unit' => 'week',
255 'subject' => 'subject sched_membership_start_1week (joined {membership.start_date})',
257 $this->fixtures
['sched_membership_end_2week'] = array(
258 'name' => 'sched_membership_end_2week',
259 'title' => 'sched_membership_end_2week',
260 'absolute_date' => '',
261 'body_html' => '<p>body sched_membership_end_2week</p>',
262 'body_text' => 'body sched_membership_end_2week',
265 'end_frequency_interval' => '',
266 'end_frequency_unit' => '',
267 'entity_status' => '',
268 'entity_value' => '',
273 'msg_template_id' => '',
275 'recipient_listing' => '',
276 'recipient_manual' => '',
277 'record_activity' => 1,
278 'repetition_frequency_interval' => '',
279 'repetition_frequency_unit' => '',
280 'start_action_condition' => 'before',
281 'start_action_date' => 'membership_end_date',
282 'start_action_offset' => '2',
283 'start_action_unit' => 'week',
284 'subject' => 'subject sched_membership_end_2week',
286 $this->fixtures
['sched_on_membership_end_date'] = array(
287 'name' => 'sched_on_membership_end_date',
288 'title' => 'sched_on_membership_end_date',
289 'body_html' => '<p>Your membership expired today</p>',
290 'body_text' => 'Your membership expired today',
293 'record_activity' => 1,
294 'start_action_condition' => 'after',
295 'start_action_date' => 'membership_end_date',
296 'start_action_offset' => '0',
297 'start_action_unit' => 'hour',
298 'subject' => 'subject send reminder on membership_end_date',
300 $this->fixtures
['sched_after_1day_membership_end_date'] = array(
301 'name' => 'sched_after_1day_membership_end_date',
302 'title' => 'sched_after_1day_membership_end_date',
303 'body_html' => '<p>Your membership expired yesterday</p>',
304 'body_text' => 'Your membership expired yesterday',
307 'record_activity' => 1,
308 'start_action_condition' => 'after',
309 'start_action_date' => 'membership_end_date',
310 'start_action_offset' => '1',
311 'start_action_unit' => 'day',
312 'subject' => 'subject send reminder on membership_end_date',
315 $this->fixtures
['sched_membership_end_2month'] = array(
316 'name' => 'sched_membership_end_2month',
317 'title' => 'sched_membership_end_2month',
318 'absolute_date' => '',
319 'body_html' => '<p>body sched_membership_end_2month</p>',
320 'body_text' => 'body sched_membership_end_2month',
323 'end_frequency_interval' => '',
324 'end_frequency_unit' => '',
325 'entity_status' => '',
326 'entity_value' => '',
331 'msg_template_id' => '',
333 'recipient_listing' => '',
334 'recipient_manual' => '',
335 'record_activity' => 1,
336 'repetition_frequency_interval' => '',
337 'repetition_frequency_unit' => '',
338 'start_action_condition' => 'after',
339 'start_action_date' => 'membership_end_date',
340 'start_action_offset' => '2',
341 'start_action_unit' => 'month',
342 'subject' => 'subject sched_membership_end_2month',
345 $this->fixtures
['sched_contact_bday_yesterday'] = array(
346 'name' => 'sched_contact_bday_yesterday',
347 'title' => 'sched_contact_bday_yesterday',
348 'absolute_date' => '',
349 'body_html' => '<p>you look like you were born yesterday!</p>',
350 'body_text' => 'you look like you were born yesterday!',
353 'end_frequency_interval' => '',
354 'end_frequency_unit' => '',
355 'entity_status' => 1,
356 'entity_value' => 'birth_date',
361 'msg_template_id' => '',
363 'recipient_listing' => '',
364 'recipient_manual' => '',
365 'record_activity' => 1,
366 'repetition_frequency_interval' => '',
367 'repetition_frequency_unit' => '',
368 'start_action_condition' => 'after',
369 'start_action_date' => 'date_field',
370 'start_action_offset' => '1',
371 'start_action_unit' => 'day',
372 'subject' => 'subject sched_contact_bday_yesterday',
375 $this->fixtures
['sched_contact_bday_anniv'] = array(
376 'name' => 'sched_contact_bday_anniv',
377 'title' => 'sched_contact_bday_anniv',
378 'absolute_date' => '',
379 'body_html' => '<p>happy birthday!</p>',
380 'body_text' => 'happy birthday!',
383 'end_frequency_interval' => '',
384 'end_frequency_unit' => '',
385 'entity_status' => 2,
386 'entity_value' => 'birth_date',
391 'msg_template_id' => '',
393 'recipient_listing' => '',
394 'recipient_manual' => '',
395 'record_activity' => 1,
396 'repetition_frequency_interval' => '',
397 'repetition_frequency_unit' => '',
398 'start_action_condition' => 'before',
399 'start_action_date' => 'date_field',
400 'start_action_offset' => '1',
401 'start_action_unit' => 'day',
402 'subject' => 'subject sched_contact_bday_anniv',
405 $this->fixtures
['sched_contact_grad_tomorrow'] = array(
406 'name' => 'sched_contact_grad_tomorrow',
407 'title' => 'sched_contact_grad_tomorrow',
408 'absolute_date' => '',
409 'body_html' => '<p>congratulations on your graduation!</p>',
410 'body_text' => 'congratulations on your graduation!',
413 'end_frequency_interval' => '',
414 'end_frequency_unit' => '',
415 'entity_status' => 1,
420 'msg_template_id' => '',
422 'recipient_listing' => '',
423 'recipient_manual' => '',
424 'record_activity' => 1,
425 'repetition_frequency_interval' => '',
426 'repetition_frequency_unit' => '',
427 'start_action_condition' => 'before',
428 'start_action_date' => 'date_field',
429 'start_action_offset' => '1',
430 'start_action_unit' => 'day',
431 'subject' => 'subject sched_contact_grad_tomorrow',
434 $this->fixtures
['sched_contact_grad_anniv'] = array(
435 'name' => 'sched_contact_grad_anniv',
436 'title' => 'sched_contact_grad_anniv',
437 'absolute_date' => '',
438 'body_html' => '<p>dear alum, please send us money.</p>',
439 'body_text' => 'dear alum, please send us money.',
442 'end_frequency_interval' => '',
443 'end_frequency_unit' => '',
444 'entity_status' => 2,
449 'msg_template_id' => '',
451 'recipient_listing' => '',
452 'recipient_manual' => '',
453 'record_activity' => 1,
454 'repetition_frequency_interval' => '',
455 'repetition_frequency_unit' => '',
456 'start_action_condition' => 'after',
457 'start_action_date' => 'date_field',
458 'start_action_offset' => '1',
459 'start_action_unit' => 'week',
460 'subject' => 'subject sched_contact_grad_anniv',
463 $this->fixtures
['sched_contact_created_yesterday'] = array(
464 'name' => 'sched_contact_created_yesterday',
465 'title' => 'sched_contact_created_yesterday',
466 'absolute_date' => '',
467 'body_html' => '<p>Your contact was created yesterday</p>',
468 'body_text' => 'Your contact was created yesterday!',
471 'end_frequency_interval' => '',
472 'end_frequency_unit' => '',
473 'entity_status' => 1,
474 'entity_value' => 'created_date',
479 'msg_template_id' => '',
481 'recipient_listing' => '',
482 'recipient_manual' => '',
483 'record_activity' => 1,
484 'repetition_frequency_interval' => '',
485 'repetition_frequency_unit' => '',
486 'start_action_condition' => 'after',
487 'start_action_date' => 'date_field',
488 'start_action_offset' => '1',
489 'start_action_unit' => 'day',
490 'subject' => 'subject sched_contact_created_yesterday',
493 $this->fixtures
['sched_contact_mod_anniv'] = array(
494 'name' => 'sched_contact_mod_anniv',
495 'title' => 'sched_contact_mod_anniv',
496 'absolute_date' => '',
497 'body_html' => '<p>You last updated your data last year</p>',
498 'body_text' => 'Go update your stuff!',
501 'end_frequency_interval' => '',
502 'end_frequency_unit' => '',
503 'entity_status' => 2,
504 'entity_value' => 'modified_date',
509 'msg_template_id' => '',
511 'recipient_listing' => '',
512 'recipient_manual' => '',
513 'record_activity' => 1,
514 'repetition_frequency_interval' => '',
515 'repetition_frequency_unit' => '',
516 'start_action_condition' => 'before',
517 'start_action_date' => 'date_field',
518 'start_action_offset' => '1',
519 'start_action_unit' => 'day',
520 'subject' => 'subject sched_contact_mod_anniv',
523 $this->fixtures
['sched_eventtype_start_1week_before'] = array(
524 'name' => 'sched_eventtype_start_1week_before',
525 'title' => 'sched_eventtype_start_1week_before',
526 'absolute_date' => '',
527 'body_html' => '<p>body sched_eventtype_start_1week_before ({event.title})</p>',
528 'body_text' => 'body sched_eventtype_start_1week_before ({event.title})',
531 'end_frequency_interval' => '',
532 'end_frequency_unit' => '',
533 // participant status id
534 'entity_status' => '',
536 'entity_value' => '',
542 'msg_template_id' => '',
544 'recipient_listing' => '',
545 'recipient_manual' => '',
546 'record_activity' => 1,
547 'repetition_frequency_interval' => '',
548 'repetition_frequency_unit' => '',
549 'start_action_condition' => 'before',
550 'start_action_date' => 'event_start_date',
551 'start_action_offset' => '1',
552 'start_action_unit' => 'week',
553 'subject' => 'subject sched_eventtype_start_1week_before ({event.title})',
555 $this->fixtures
['sched_eventtype_end_2month_repeat_twice_2_weeks'] = array(
556 'name' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
557 'title' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
558 'absolute_date' => '',
559 'body_html' => '<p>body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}</p>',
560 'body_text' => 'body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
561 'end_action' => 'after',
562 'end_date' => 'event_end_date',
563 'end_frequency_interval' => '3',
564 'end_frequency_unit' => 'month',
565 // participant status id
566 'entity_status' => '',
568 'entity_value' => '',
574 'msg_template_id' => '',
576 'recipient_listing' => '',
577 'recipient_manual' => '',
578 'record_activity' => 1,
579 'repetition_frequency_interval' => '2',
580 'repetition_frequency_unit' => 'week',
581 'start_action_condition' => 'after',
582 'start_action_date' => 'event_end_date',
583 'start_action_offset' => '2',
584 'start_action_unit' => 'month',
585 'subject' => 'subject sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
588 $this->fixtures
['sched_membership_end_2month_repeat_twice_4_weeks'] = array(
589 'name' => 'sched_membership_end_2month',
590 'title' => 'sched_membership_end_2month',
591 'absolute_date' => '',
592 'body_html' => '<p>body sched_membership_end_2month</p>',
593 'body_text' => 'body sched_membership_end_2month',
595 'end_date' => 'membership_end_date',
596 'end_frequency_interval' => '4',
597 'end_frequency_unit' => 'month',
598 'entity_status' => '',
599 'entity_value' => '',
604 'msg_template_id' => '',
606 'recipient_listing' => '',
607 'recipient_manual' => '',
608 'record_activity' => 1,
609 'repetition_frequency_interval' => '4',
610 'repetition_frequency_unit' => 'week',
611 'start_action_condition' => 'after',
612 'start_action_date' => 'membership_end_date',
613 'start_action_offset' => '2',
614 'start_action_unit' => 'month',
615 'subject' => 'subject sched_membership_end_2month',
617 $this->fixtures
['sched_membership_end_limit_to_none'] = array(
618 'name' => 'limit to none',
619 'title' => 'limit to none',
620 'absolute_date' => '',
621 'body_html' => '<p>body sched_membership_end_2month</p>',
622 'body_text' => 'body sched_membership_end_2month',
625 'end_frequency_interval' => '4',
626 'end_frequency_unit' => 'month',
627 'entity_status' => '',
628 'entity_value' => '',
634 'msg_template_id' => '',
636 'recipient_listing' => '',
637 'recipient_manual' => '',
638 'record_activity' => 1,
639 'repetition_frequency_interval' => '4',
640 'repetition_frequency_unit' => 'week',
641 'start_action_condition' => 'after',
642 'start_action_date' => 'membership_end_date',
643 'start_action_offset' => '2',
644 'start_action_unit' => 'month',
645 'subject' => 'limit to none',
647 $this->fixtures
['sched_on_membership_end_date_repeat_interval'] = array(
648 'name' => 'sched_on_membership_end_date',
649 'title' => 'sched_on_membership_end_date',
650 'body_html' => '<p>Your membership expired 1 unit ago</p>',
651 'body_text' => 'Your membership expired 1 unit ago',
652 'end_frequency_interval' => 10,
653 'end_frequency_unit' => 'year',
657 'record_activity' => 1,
658 'start_action_condition' => 'after',
659 'start_action_date' => 'membership_end_date',
660 'start_action_offset' => '0',
661 'start_action_unit' => 'hour',
662 'subject' => 'subject send reminder every unit after membership_end_date',
665 $customGroup = $this->callAPISuccess('CustomGroup', 'create', array(
666 'title' => ts('Test Contact Custom group'),
667 'name' => 'test_contact_cg',
668 'extends' => 'Contact',
669 'domain_id' => CRM_Core_Config
::domainID(),
671 'collapse_adv_display' => 0,
672 'collapse_display' => 0,
674 $customField = $this->callAPISuccess('CustomField', 'create', array(
675 'label' => 'Test Text',
676 'data_type' => 'String',
677 'html_type' => 'Text',
678 'custom_group_id' => $customGroup['id'],
680 $this->fixtures
['contact_custom_token'] = array(
681 'id' => $customField['id'],
682 'token' => sprintf('{contact.custom_%s}', $customField['id']),
683 'name' => sprintf('custom_%s', $customField['id']),
684 'value' => 'text ' . substr(sha1(rand()), 0, 7),
691 * Tears down the fixture, for example, closes a network connection.
693 * This method is called after a test is executed.
695 public function tearDown() {
697 $this->mut
->clearMessages();
700 $this->quickCleanup(array(
701 'civicrm_action_schedule',
702 'civicrm_action_log',
703 'civicrm_membership',
704 'civicrm_participant',
708 $this->callAPISuccess('CustomField', 'delete', array('id' => $this->fixtures
['contact_custom_token']['id']));
709 $this->callAPISuccess('CustomGroup', 'delete', array(
710 'id' => CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomGroup', 'test_contact_cg', 'id', 'name'),
715 public function mailerExamples() {
718 // Some tokens - short as subject has 128char limit in DB.
719 $someTokensTmpl = implode(';;', array(
720 // basic contact token
721 '{contact.display_name}',
722 // funny legacy contact token
724 // funny legacy contact token
725 '{contact.gender_id}',
728 // action-scheduler token
729 '{activity.activity_type}',
731 // Further tokens can be tested in the body text/html.
732 $manyTokensTmpl = implode(';;', array(
734 '{contact.email_greeting}',
735 $this->fixture
['contact_custom_token']['token'],
737 // Note: The behavior of domain-tokens on a scheduled reminder is undefined. All we
738 // can really do is check that it has something.
739 $someTokensExpected = 'Churmondleia Ōtākou;;Female;;Female;;[a-zA-Z0-9 ]+;;Phone Call';
740 $manyTokensExpected = sprintf('%s;;Dear Churmondleia;;%s', $someTokensExpected, $this->fixture
['contact_custom_token']['value']);
742 // In this example, we use a lot of tokens cutting across multiple components.
744 // Schedule definition.
746 'subject' => "subj $someTokensTmpl",
747 'body_html' => "html $manyTokensTmpl",
748 'body_text' => "text $manyTokensTmpl",
750 // Assertions (regex).
752 'from_name' => "/^FIXME\$/",
753 'from_email' => "/^info@EXAMPLE.ORG\$/",
754 'subject' => "/^subj $someTokensExpected\$/",
755 'body_html' => "/^html $manyTokensExpected\$/",
756 'body_text' => "/^text $manyTokensExpected\$/",
760 // In this example, we customize the from address.
762 // Schedule definition.
764 'from_name' => 'Bob',
765 'from_email' => 'bob@example.org',
767 // Assertions (regex).
769 'from_name' => "/^Bob\$/",
770 'from_email' => "/^bob@example.org\$/",
774 // In this example, we autoconvert HTML to text
776 // Schedule definition.
778 'body_html' => '<p>Hello & stuff.</p>',
781 // Assertions (regex).
783 'body_html' => '/^' . preg_quote('<p>Hello & stuff.</p>', '/') . '/',
784 'body_text' => '/^' . preg_quote('Hello & stuff.', '/') . '/',
788 // In this example, we autoconvert HTML to text
790 // Schedule definition.
793 'body_text' => 'Hello world',
795 // Assertions (regex).
797 'body_html' => '/^--UNDEFINED--$/',
798 'body_text' => '/^Hello world$/',
806 * This generates a single mailing through the scheduled-reminder
807 * system (using an activity-reminder as a baseline) and
808 * checks that the resulting message satisfies various
809 * regular expressions.
811 * @param array $schedule
812 * Values to set/override in the schedule.
813 * Ex: array('subject' => 'Hello, {contact.first_name}!').
814 * @param array $patterns
815 * A list of regexes to compare with the actual email.
816 * Ex: array('subject' => '/^Hello, Alice!/').
817 * Keys: subject, body_text, body_html, from_name, from_email.
818 * @dataProvider mailerExamples
820 public function testMailer($schedule, $patterns) {
821 $actionSchedule = array_merge($this->fixtures
['sched_activity_1day'], $schedule);
822 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
823 $this->assertTrue(is_numeric($actionScheduleDao->id
));
825 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures
['phonecall']);
826 $this->assertTrue(is_numeric($activity->id
));
827 $contact = $this->callAPISuccess('contact', 'create', array_merge(
828 $this->fixtures
['contact'],
830 $this->fixtures
['contact_custom_token']['name'] => $this->fixtures
['contact_custom_token']['value'],
835 $source['contact_id'] = $contact['id'];
836 $source['activity_id'] = $activity->id
;
837 $source['record_type_id'] = 2;
838 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
839 $activityContact->save();
841 CRM_Utils_Time
::setTime('2012-06-14 15:00:00');
842 $this->callAPISuccess('job', 'send_reminder', array());
843 $this->mut
->assertRecipients(array(array('test-member@example.com')));
844 foreach ($this->mut
->getAllMessages('ezc') as $message) {
845 /** @var ezcMail $message */
847 $messageArray = array();
848 $messageArray['subject'] = $message->subject
;
849 $messageArray['from_name'] = $message->from
->name
;
850 $messageArray['from_email'] = $message->from
->email
;
851 $messageArray['body_text'] = '--UNDEFINED--';
852 $messageArray['body_html'] = '--UNDEFINED--';
854 foreach ($message->fetchParts() as $part) {
855 /** @var ezcMailText ezcMailText */
856 if ($part instanceof ezcMailText
&& $part->subType
== 'html') {
857 $messageArray['body_html'] = $part->text
;
859 if ($part instanceof ezcMailText
&& $part->subType
== 'plain') {
860 $messageArray['body_text'] = $part->text
;
864 foreach ($patterns as $field => $pattern) {
865 $this->assertRegExp($pattern, $messageArray[$field],
866 "Check that '$field'' matches regex. " . print_r(array('expected' => $patterns, 'actual' => $messageArray), 1));
869 $this->mut
->clearMessages();
872 public function testActivityDateTimeMatchNonRepeatableSchedule() {
873 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($this->fixtures
['sched_activity_1day']);
874 $this->assertTrue(is_numeric($actionScheduleDao->id
));
876 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures
['phonecall']);
877 $this->assertTrue(is_numeric($activity->id
));
878 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures
['contact']);
879 $activity->subject
= "Test subject for Phonecall";
882 $source['contact_id'] = $contact['id'];
883 $source['activity_id'] = $activity->id
;
884 $source['record_type_id'] = 2;
885 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
886 $activityContact->save();
888 $this->assertCronRuns(array(
890 // Before the 24-hour mark, no email
891 'time' => '2012-06-14 04:00:00',
892 'recipients' => array(),
893 'subjects' => array(),
896 // After the 24-hour mark, an email
897 'time' => '2012-06-14 15:00:00',
898 'recipients' => array(array('test-member@example.com')),
899 'subjects' => array('1-Day (non-repeating) (about Phone Call)'),
902 // Run cron again; message already sent
904 'recipients' => array(),
907 $activityTypes = CRM_Core_PseudoConstant
::activityType(TRUE, FALSE, FALSE, 'name');
908 $activityDAO = new CRM_Activity_DAO_Activity();
909 $activityDAO->source_record_id
= $activity->id
;
910 $activityDAO->activity_type_id
= array_search('Reminder Sent', $activityTypes);
911 $activityDAO->find();
912 while ($activityDAO->fetch()) {
913 $this->assertContains($activity->subject
, $activityDAO->details
);
917 public function testActivityDateTimeMatchRepeatableSchedule() {
918 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($this->fixtures
['sched_activity_1day_r']);
919 $this->assertTrue(is_numeric($actionScheduleDao->id
));
921 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures
['phonecall']);
922 $this->assertTrue(is_numeric($activity->id
));
923 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures
['contact']);
926 $source['contact_id'] = $contact['id'];
927 $source['activity_id'] = $activity->id
;
928 $source['record_type_id'] = 2;
929 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
930 $activityContact->save();
932 $this->assertCronRuns(array(
934 // Before the 24-hour mark, no email
935 'time' => '012-06-14 04:00:00',
936 'recipients' => array(),
937 'subjects' => array(),
940 // After the 24-hour mark, an email
941 'time' => '2012-06-14 15:00:00',
942 'recipients' => array(array('test-member@example.com')),
943 'subjects' => array('1-Day (repeating) (about Phone Call)'),
946 // Run cron 4 hours later; first message already sent
947 'time' => '2012-06-14 20:00:00',
948 'recipients' => array(),
949 'subjects' => array(),
952 // Run cron 6 hours later; send second message.
953 'time' => '2012-06-14 21:00:01',
954 'recipients' => array(array('test-member@example.com')),
955 'subjects' => array('1-Day (repeating) (about Phone Call)'),
960 public function testActivityDateTimeMatchRepeatableScheduleOnAbsDate() {
961 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($this->fixtures
['sched_activity_1day_r_on_abs_date']);
962 $this->assertTrue(is_numeric($actionScheduleDao->id
));
964 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures
['phonecall']);
965 $this->assertTrue(is_numeric($activity->id
));
966 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures
['contact']);
969 $source['contact_id'] = $contact['id'];
970 $source['activity_id'] = $activity->id
;
971 $source['record_type_id'] = 2;
972 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
973 $activityContact->save();
975 $this->assertCronRuns(array(
977 // Before the 24-hour mark, no email
978 'time' => '2012-06-13 04:00:00',
979 'recipients' => array(),
980 'subjects' => array(),
983 // On absolute date set on 2012-06-14
984 'time' => '2012-06-14 00:00:00',
985 'recipients' => array(array('test-member@example.com')),
986 'subjects' => array('1-Day (repeating) (about Phone Call)'),
989 // Run cron 4 hours later; first message already sent
990 'time' => '2012-06-14 04:00:00',
991 'recipients' => array(),
992 'subjects' => array(),
995 // Run cron 6 hours later; send second message.
996 'time' => '2012-06-14 06:00:01',
997 'recipients' => array(array('test-member@example.com')),
998 'subjects' => array('1-Day (repeating) (about Phone Call)'),
1004 * For contacts/activities which don't match the schedule filter,
1005 * an email should *not* be sent.
1007 // TODO // function testActivityDateTime_NonMatch() { }
1010 * For contacts/members which match schedule based on join/start date,
1011 * an email should be sent.
1013 public function testMembershipDateMatch() {
1014 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 1)));
1015 $this->assertTrue(is_numeric($membership->id
));
1016 $result = $this->callAPISuccess('Email', 'create', array(
1017 'contact_id' => $membership->contact_id
,
1018 'email' => 'test-member@example.com',
1019 'location_type_id' => 1,
1023 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1024 $actionSchedule = $this->fixtures
['sched_membership_join_2week'];
1025 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1026 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1027 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1029 // start_date=2012-03-15 ; schedule is 2 weeks after join_date
1030 $this->assertCronRuns(array(
1032 // Before the 2-week mark, no email.
1033 'time' => '2012-03-28 01:00:00',
1034 'recipients' => array(),
1035 'subjects' => array(),
1038 // After the 2-week mark, send an email.
1039 'time' => '2012-03-29 01:00:00',
1040 'recipients' => array(array('test-member@example.com')),
1041 'subjects' => array('subject sched_membership_join_2week (joined March 15th, 2012)'),
1045 $actionSchedule = $this->fixtures
['sched_membership_start_1week'];
1046 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1047 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1048 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1050 // start_date=2012-03-15 ; schedule is 1 weeks after start_date
1051 $this->assertCronRuns(array(
1053 // Before the 2-week mark, no email.
1054 'time' => '2012-03-21 01:00:00',
1055 'recipients' => array(),
1056 'subjects' => array(),
1059 // After the 2-week mark, send an email.
1060 'time' => '2012-03-22 01:00:00',
1061 'recipients' => array(array('test-member@example.com')),
1062 'subjects' => array('subject sched_membership_start_1week (joined March 15th, 2012)'),
1068 * CRM-21675: Support parent and smart group in 'Limit to' field
1070 public function testScheduleReminderWithParentGroup() {
1071 // Contact A with birth-date at '07-07-2005' and gender - Male, later got added in smart group
1072 $contactID1 = $this->individualCreate(array('birth_date' => '20050707', 'gender_id' => 1, 'email' => 'abc@test.com'));
1073 // Contact B with birth-date at '07-07-2005', later got added in regular group
1074 $contactID2 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'def@test.com'), 1);
1075 // Contact C with birth-date at '07-07-2005', but not included in any group
1076 $contactID3 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'ghi@test.com'), 2);
1078 // create regular group and add Contact B to it
1079 $groupID = $this->groupCreate();
1080 $this->callAPISuccess('GroupContact', 'Create', array(
1081 'group_id' => $groupID,
1082 'contact_id' => $contactID2,
1085 // create smart group which will contain all Male contacts
1086 $smartGroupParams = array('formValues' => array('gender_id' => 1));
1087 $smartGroupID = $this->smartGroupCreate(
1090 'name' => 'new_smart_group',
1091 'title' => 'New Smart Group',
1092 'parents' => array($groupID => 1),
1096 $actionScheduleParams = array(
1097 'name' => 'sched_contact_bday_yesterday',
1098 'title' => 'sched_contact_bday_yesterday',
1099 'absolute_date' => '',
1100 'body_html' => '<p>you look like you were born yesterday!</p>',
1101 'body_text' => 'you look like you were born yesterday!',
1104 'end_frequency_interval' => '',
1105 'end_frequency_unit' => '',
1106 'entity_status' => 1,
1107 'entity_value' => 'birth_date',
1109 'group_id' => $groupID,
1113 'msg_template_id' => '',
1115 'recipient_listing' => '',
1116 'recipient_manual' => '',
1117 'record_activity' => 1,
1118 'repetition_frequency_interval' => '',
1119 'repetition_frequency_unit' => '',
1120 'start_action_condition' => 'after',
1121 'start_action_date' => 'date_field',
1122 'start_action_offset' => '1',
1123 'start_action_unit' => 'day',
1124 'subject' => 'subject sched_contact_bday_yesterday',
1127 // Create schedule reminder where parent group ($groupID) is selectd to limit recipients,
1128 // which contain a individual contact - $contactID2 and is parent to smart group.
1129 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionScheduleParams);
1130 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1131 $this->assertCronRuns(array(
1133 // On the birthday, no email.
1134 'time' => '2005-07-07 01:00:00',
1135 'recipients' => array(),
1138 // The next day, send an email.
1139 'time' => '2005-07-08 20:00:00',
1140 'recipients' => array(
1150 $this->groupDelete($smartGroupID);
1151 $this->groupDelete($groupID);
1155 * Test end date email sent.
1157 * For contacts/members which match schedule based on join date,
1158 * an email should be sent.
1160 public function testMembershipJoinDateNonMatch() {
1161 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures
['rolling_membership']);
1162 $this->assertTrue(is_numeric($membership->id
));
1163 $result = $this->callAPISuccess('Email', 'create', array(
1164 'contact_id' => $membership->contact_id
,
1165 'location_type_id' => 1,
1166 'email' => 'test-member@example.com',
1169 // Add an alternative membership type, and only send messages for that type
1170 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
1171 $this->assertTrue(is_numeric($extraMembershipType->id
));
1172 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($this->fixtures
['sched_membership_join_2week']);
1173 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1174 $actionScheduleDao->entity_value
= $extraMembershipType->id
;
1175 $actionScheduleDao->save();
1177 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1178 $this->assertCronRuns(array(
1180 // After the 2-week mark, don't send email because we have different membership type.
1181 'time' => '2012-03-29 01:00:00',
1182 'recipients' => array(),
1188 * Test that the first and SECOND notifications are sent out.
1190 public function testMembershipEndDateRepeat() {
1191 // creates membership with end_date = 20120615
1192 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 2)));
1193 $result = $this->callAPISuccess('Email', 'create', array(
1194 'contact_id' => $membership->contact_id
,
1195 'email' => 'test-member@example.com',
1197 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1199 $actionSchedule = $this->fixtures
['sched_membership_end_2month_repeat_twice_4_weeks'];
1200 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1201 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1203 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1204 $this->assertCronRuns(array(
1206 // After the 2-week mark, send an email.
1207 'time' => '2012-08-15 01:00:00',
1208 'recipients' => array(array('test-member@example.com')),
1211 // After the 2-week mark, send an email.
1212 'time' => '2012-09-12 01:00:00',
1213 'recipients' => array(array('test-member@example.com')),
1219 * Test behaviour when date changes.
1221 * Test that the first notification is sent but the second is NOT sent if the end date changes in
1225 public function testMembershipEndDateRepeatChangedEndDate_CRM_15376() {
1226 // creates membership with end_date = 20120615
1227 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 2)));
1228 $this->callAPISuccess('Email', 'create', array(
1229 'contact_id' => $membership->contact_id
,
1230 'email' => 'test-member@example.com',
1232 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1234 $actionSchedule = $this->fixtures
['sched_membership_end_2month_repeat_twice_4_weeks'];
1235 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1236 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1237 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1238 $this->assertCronRuns(array(
1240 // After the 2-week mark, send an email.
1241 'time' => '2012-08-15 01:00:00',
1242 'recipients' => array(array('test-member@example.com')),
1246 // Extend membership - reminder should NOT go out.
1247 $this->callAPISuccess('membership', 'create', array('id' => $membership->id
, 'end_date' => '2014-01-01'));
1248 $this->assertCronRuns(array(
1250 // After the 2-week mark, send an email.
1251 'time' => '2012-09-12 01:00:00',
1252 'recipients' => array(),
1258 * Test membership end date email sends.
1260 * For contacts/members which match schedule based on end date,
1261 * an email should be sent.
1263 public function testMembershipEndDateMatch() {
1264 // creates membership with end_date = 20120615
1265 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 2)));
1266 $this->assertTrue(is_numeric($membership->id
));
1267 $this->callAPISuccess('Email', 'create', array(
1268 'contact_id' => $membership->contact_id
,
1269 'email' => 'test-member@example.com',
1271 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1273 $actionSchedule = $this->fixtures
['sched_membership_end_2week'];
1274 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1275 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1276 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1278 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1279 $this->assertCronRuns(array(
1281 // Before the 2-week mark, no email.
1282 'time' => '2012-05-31 01:00:00',
1283 // 'time' => '2012-06-01 01:00:00',
1284 // FIXME: Is this the right boundary?
1285 'recipients' => array(),
1288 // After the 2-week mark, send an email.
1289 'time' => '2012-06-01 01:00:00',
1290 'recipients' => array(array('test-member@example.com')),
1294 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
1295 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
1296 $membership->end_date
= '2012-09-15';
1297 $membership->save();
1299 //change the email id of chosen membership contact to assert
1300 //recipient of not the previously sent mail but the new one
1301 $result = $this->callAPISuccess('Email', 'create', array(
1303 'contact_id' => $membership->contact_id
,
1304 'email' => 'member2@example.com',
1306 $this->assertAPISuccess($result);
1308 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
1309 $this->assertCronRuns(array(
1311 // Before the 2-week mark, no email
1312 'time' => '2012-08-31 01:00:00',
1313 'recipients' => array(),
1315 //array( // After the 2-week mark, send an email
1316 //'time' => '2012-09-01 01:00:00',
1317 //'recipients' => array(array('member2@example.com')),
1323 * Test membership end date email.
1325 * For contacts/members which match schedule based on end date,
1326 * an email should be sent.
1328 public function testMembershipEndDateNoMatch() {
1329 // creates membership with end_date = 20120615
1330 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 3)));
1331 $this->assertTrue(is_numeric($membership->id
));
1332 $result = $this->callAPISuccess('Email', 'create', array(
1333 'contact_id' => $membership->contact_id
,
1334 'email' => 'test-member@example.com',
1336 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1338 $actionSchedule = $this->fixtures
['sched_membership_end_2month'];
1339 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1340 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1341 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1343 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1344 $this->assertCronRuns(array(
1346 // Before the 2-week mark, no email.
1347 'time' => '2012-05-31 01:00:00',
1348 // 'time' => '2012-06-01 01:00:00',
1349 // FIXME: Is this the right boundary?
1350 'recipients' => array(),
1353 // After the 2-week mark, send an email.
1354 'time' => '2013-05-01 01:00:00',
1355 'recipients' => array(),
1360 public function testContactBirthDateNoAnniv() {
1361 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures
['contact_birthdate']);
1362 $this->_testObjects
['CRM_Contact_DAO_Contact'][] = $contact['id'];
1363 $actionSchedule = $this->fixtures
['sched_contact_bday_yesterday'];
1364 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1365 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1366 $this->assertCronRuns(array(
1368 // On the birthday, no email.
1369 'time' => '2005-07-07 01:00:00',
1370 'recipients' => array(),
1373 // The next day, send an email.
1374 'time' => '2005-07-08 20:00:00',
1375 'recipients' => array(array('test-bday@example.com')),
1380 public function testContactBirthDateAnniversary() {
1381 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures
['contact_birthdate']);
1382 $this->_testObjects
['CRM_Contact_DAO_Contact'][] = $contact['id'];
1383 $actionSchedule = $this->fixtures
['sched_contact_bday_anniv'];
1384 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1385 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1386 $this->assertCronRuns(array(
1388 // On some random day, no email.
1389 'time' => '2014-03-07 01:00:00',
1390 'recipients' => array(),
1393 // On the eve of their 9th birthday, send an email.
1394 'time' => '2014-07-06 20:00:00',
1395 'recipients' => array(array('test-bday@example.com')),
1400 public function testContactCustomDateNoAnniv() {
1402 'title' => 'Test_Group',
1403 'name' => 'test_group',
1404 'extends' => array('Individual'),
1405 'style' => 'Inline',
1406 'is_multiple' => FALSE,
1409 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
1411 'label' => 'Graduation',
1412 'data_type' => 'Date',
1413 'html_type' => 'Select Date',
1414 'custom_group_id' => $createGroup['id'],
1416 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1417 $contactParams = $this->fixtures
['contact'];
1418 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
1419 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
1420 $this->_testObjects
['CRM_Contact_DAO_Contact'][] = $contact['id'];
1421 $actionSchedule = $this->fixtures
['sched_contact_grad_tomorrow'];
1422 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1423 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1424 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1425 $this->assertCronRuns(array(
1427 // On some random day, no email.
1428 'time' => '2014-03-07 01:00:00',
1429 'recipients' => array(),
1432 // On the eve of their graduation, send an email.
1433 'time' => '2013-12-15 20:00:00',
1434 'recipients' => array(array('test-member@example.com')),
1437 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
1440 public function testContactCreatedNoAnniv() {
1441 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures
['contact_birthdate']);
1442 $this->_testObjects
['CRM_Contact_DAO_Contact'][] = $contact['id'];
1443 $actionSchedule = $this->fixtures
['sched_contact_created_yesterday'];
1444 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1445 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1446 $this->assertCronRuns(array(
1448 // On the date created, no email.
1449 'time' => $contact['values'][$contact['id']]['created_date'],
1450 'recipients' => array(),
1453 // The next day, send an email.
1454 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['created_date'] . ' +1 day')),
1455 'recipients' => array(array('test-bday@example.com')),
1460 public function testContactModifiedAnniversary() {
1461 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures
['contact_birthdate']);
1462 $this->_testObjects
['CRM_Contact_DAO_Contact'][] = $contact['id'];
1463 $modifiedDate = $this->callAPISuccess('Contact', 'getvalue', array('id' => $contact['id'], 'return' => 'modified_date'));
1464 $actionSchedule = $this->fixtures
['sched_contact_mod_anniv'];
1465 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1466 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1467 $this->assertCronRuns(array(
1469 // On some random day, no email.
1470 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' -60 days')),
1471 'recipients' => array(),
1474 // On the eve of 3 years after they were modified, send an email.
1475 'time' => date('Y-m-d H:i:s', strtotime($modifiedDate . ' +3 years -1 day')),
1476 'recipients' => array(array('test-bday@example.com')),
1482 * Check that limit_to + an empty recipients doesn't sent to multiple contacts.
1484 public function testMembershipLimitToNone() {
1485 // creates membership with end_date = 20120615
1486 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 2)));
1488 $this->assertTrue(is_numeric($membership->id
));
1489 $result = $this->callAPISuccess('Email', 'create', array(
1490 'contact_id' => $membership->contact_id
,
1491 'email' => 'member@example.com',
1493 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1494 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
1496 $this->assertAPISuccess($result);
1498 $actionSchedule = $this->fixtures
['sched_membership_end_limit_to_none'];
1499 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1500 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1501 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1503 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1504 $this->assertCronRuns(array(
1506 // Before the 2-week mark, no email.
1507 'time' => '2012-05-31 01:00:00',
1508 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
1509 'recipients' => array(),
1514 public function testMembership_referenceDate() {
1515 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 2)));
1517 $this->assertTrue(is_numeric($membership->id
));
1518 $result = $this->callAPISuccess('Email', 'create', array(
1519 'contact_id' => $membership->contact_id
,
1520 'email' => 'member@example.com',
1523 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1524 $this->assertAPISuccess($result);
1526 $actionSchedule = $this->fixtures
['sched_membership_join_2week'];
1527 $actionSchedule['entity_value'] = $membership->membership_type_id
;
1528 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1529 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1531 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1532 $this->assertCronRuns(array(
1534 // After the 2-week mark, send an email
1535 'time' => '2012-03-29 01:00:00',
1536 'recipients' => array(array('member@example.com')),
1539 // After the 2-week 1day mark, don't send an email
1540 'time' => '2012-03-30 01:00:00',
1541 'recipients' => array(),
1545 //check if reference date is set to membership's join date
1546 //as per the action_start_date chosen for current schedule reminder
1547 $this->assertEquals('2012-03-15',
1548 CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_ActionLog', $membership->contact_id
, 'reference_date', 'contact_id')
1551 //change current membership join date that may signifies as membership renewal activity
1552 $membership->join_date
= '2012-03-29';
1553 $membership->save();
1555 $this->assertCronRuns(array(
1557 // After the 13 days of the changed join date 2012-03-29, don't send an email
1558 'time' => '2012-04-11 01:00:00',
1559 'recipients' => array(),
1562 // After the 2-week of the changed join date 2012-03-29, send an email
1563 'time' => '2012-04-12 01:00:00',
1564 'recipients' => array(array('member@example.com')),
1567 $this->assertCronRuns(array(
1569 // It should not re-send on the same day
1570 'time' => '2012-04-12 01:00:00',
1571 'recipients' => array(),
1576 public function testMembershipOnMultipleReminder() {
1577 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures
['rolling_membership'], array('status_id' => 2)));
1579 $this->assertTrue(is_numeric($membership->id
));
1580 $result = $this->callAPISuccess('Email', 'create', array(
1581 'contact_id' => $membership->contact_id
,
1582 'email' => 'member@example.com',
1584 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $membership->contact_id
)));
1585 $this->assertAPISuccess($result);
1587 // Send email 2 weeks before end_date
1588 $actionScheduleBefore = $this->fixtures
['sched_membership_end_2week'];
1589 // Send email on end_date/expiry date
1590 $actionScheduleOn = $this->fixtures
['sched_on_membership_end_date'];
1591 // Send email 1 day after end_date/grace period
1592 $actionScheduleAfter = $this->fixtures
['sched_after_1day_membership_end_date'];
1593 $actionScheduleBefore['entity_value'] = $actionScheduleOn['entity_value'] = $actionScheduleAfter['entity_value'] = $membership->membership_type_id
;
1594 foreach (array('actionScheduleBefore', 'actionScheduleOn', 'actionScheduleAfter') as $value) {
1595 $
$value = CRM_Core_BAO_ActionSchedule
::add($
$value);
1596 $this->assertTrue(is_numeric($
$value->id
));
1599 $this->assertCronRuns(
1602 // 1day 2weeks before membership end date(MED), don't send mail
1603 'time' => '2012-05-31 01:00:00',
1604 'recipients' => array(),
1607 // 2 weeks before MED, send an email
1608 'time' => '2012-06-01 01:00:00',
1609 'recipients' => array(array('member@example.com')),
1612 // 1day before MED, don't send mail
1613 'time' => '2012-06-14 01:00:00',
1614 'recipients' => array(),
1617 // On MED, send an email
1618 'time' => '2012-06-15 00:00:00',
1619 'recipients' => array(array('member@example.com')),
1622 // After 1day of MED, send an email
1623 'time' => '2012-06-16 01:00:00',
1624 'recipients' => array(array('member@example.com')),
1627 // After 1day 1min of MED, don't send an email
1628 'time' => '2012-06-17 00:01:00',
1629 'recipients' => array(),
1634 // Assert the timestamp as of when the emails of respective three reminders as configured
1635 // 2 weeks before, on and 1 day after MED, are sent
1636 $this->assertApproxEquals(
1637 strtotime('2012-06-01 01:00:00'),
1638 strtotime(CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleBefore->id
, 'action_date_time', 'action_schedule_id', TRUE)),
1639 // Variation in test execution time.
1642 $this->assertApproxEquals(
1643 strtotime('2012-06-15 00:00:00'),
1644 strtotime(CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleOn->id
, 'action_date_time', 'action_schedule_id', TRUE)),
1645 // Variation in test execution time.
1648 $this->assertApproxEquals(
1649 strtotime('2012-06-16 01:00:00'),
1650 strtotime(CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleAfter->id
, 'action_date_time', 'action_schedule_id', TRUE)),
1651 // Variation in test execution time.
1655 //extend MED to 2 weeks after the current MED (that may signifies as membership renewal activity)
1656 // and lets assert as of when the new set of reminders will be sent against their respective Schedule Reminders(SR)
1657 $membership->end_date
= '2012-06-20';
1658 $membership->save();
1660 $result = $this->callAPISuccess('Contact', 'get', array('id' => $membership->contact_id
));
1661 $this->assertCronRuns(
1664 // 1day 2weeks before membership end date(MED), don't send mail
1665 'time' => '2012-06-05 01:00:00',
1666 'recipients' => array(),
1669 // 2 weeks before MED, send an email
1670 'time' => '2012-06-06 01:00:00',
1671 'recipients' => array(array('member@example.com')),
1674 // 1day before MED, don't send mail
1675 'time' => '2012-06-19 01:00:00',
1676 'recipients' => array(),
1679 // On MED, send an email
1680 'time' => '2012-06-20 00:00:00',
1681 'recipients' => array(array('member@example.com')),
1684 // After 1day of MED, send an email
1685 'time' => '2012-06-21 01:00:00',
1686 'recipients' => array(array('member@example.com')),
1689 // After 1day 1min of MED, don't send an email
1690 'time' => '2012-07-21 00:01:00',
1691 'recipients' => array(),
1696 public function testContactCustomDate_Anniv() {
1698 'title' => 'Test_Group now',
1699 'name' => 'test_group_now',
1700 'extends' => array('Individual'),
1701 'style' => 'Inline',
1702 'is_multiple' => FALSE,
1705 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
1707 'label' => 'Graduation',
1708 'data_type' => 'Date',
1709 'html_type' => 'Select Date',
1710 'custom_group_id' => $createGroup['id'],
1712 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1714 $contactParams = $this->fixtures
['contact'];
1715 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
1716 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
1717 $this->_testObjects
['CRM_Contact_DAO_Contact'][] = $contact['id'];
1718 $actionSchedule = $this->fixtures
['sched_contact_grad_anniv'];
1719 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1720 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
1721 $this->assertTrue(is_numeric($actionScheduleDao->id
));
1722 $this->assertCronRuns(array(
1724 // On some random day, no email.
1725 'time' => '2014-03-07 01:00:00',
1726 'recipients' => array(),
1729 // A week after their 5th anniversary of graduation, send an email.
1730 'time' => '2018-12-23 20:00:00',
1731 'recipients' => array(array('test-member@example.com')),
1734 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
1738 * Test sched reminder set via registration date.
1740 public function testEventTypeRegistrationDate() {
1742 $contactParams = array(
1743 'email' => 'test-event@example.com',
1745 $contact = $this->individualCreate($contactParams);
1746 //Add it as a participant to an event ending registration - 7 days from now.
1748 'start_date' => date('Ymd', strtotime('-5 day')),
1749 'end_date' => date('Ymd', strtotime('+7 day')),
1750 'registration_start_date' => date('Ymd', strtotime('-5 day')),
1751 'registration_end_date' => date('Ymd', strtotime('+7 day')),
1753 $event = $this->eventCreate($params);
1754 $this->participantCreate(array('contact_id' => $contact, 'event_id' => $event['id']));
1756 //Create a scheduled reminder to send email 7 days before registration date.
1757 $actionSchedule = $this->fixtures
['sched_eventtype_start_1week_before'];
1758 $actionSchedule['start_action_offset'] = 7;
1759 $actionSchedule['start_action_unit'] = 'day';
1760 $actionSchedule['start_action_date'] = 'registration_end_date';
1761 $actionSchedule['entity_value'] = $event['values'][$event['id']]['event_type_id'];
1762 $actionSchedule['entity_status'] = $this->callAPISuccessGetValue('ParticipantStatusType', array(
1764 'name' => "Attended",
1766 $actionSched = $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1767 //Run the cron and verify if an email was sent.
1768 $this->assertCronRuns(array(
1770 'time' => date('Y-m-d'),
1771 'recipients' => array(array('test-event@example.com')),
1776 $contactParams = array(
1777 'email' => 'test-event2@example.com',
1779 $contact2 = $this->individualCreate($contactParams);
1780 //Create an event with registration end date = 2 week from now.
1781 $params['end_date'] = date('Ymd', strtotime('+2 week'));
1782 $params['registration_end_date'] = date('Ymd', strtotime('+2 week'));
1783 $event2 = $this->eventCreate($params);
1784 $this->participantCreate(array('contact_id' => $contact2, 'event_id' => $event2['id']));
1786 //Assert there is no reminder sent to the contact.
1787 $this->assertCronRuns(array(
1789 'time' => date('Y-m-d'),
1790 'recipients' => array(),
1794 //Modify the sched reminder to be sent 2 week from registration end date.
1795 $this->callAPISuccess('action_schedule', 'create', array(
1796 'id' => $actionSched['id'],
1797 'start_action_offset' => 2,
1798 'start_action_unit' => 'week',
1801 //Contact should receive the reminder now.
1802 $this->assertCronRuns(array(
1804 'time' => date('Y-m-d'),
1805 'recipients' => array(array('test-event2@example.com')),
1811 * Test sched reminder set via start date.
1813 public function testEventTypeStartDate() {
1814 // Create event+participant with start_date = 20120315, end_date = 20120615.
1815 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures
['participant'], array('status_id' => 2)));
1816 $this->callAPISuccess('Email', 'create', array(
1817 'contact_id' => $participant->contact_id
,
1818 'email' => 'test-event@example.com',
1820 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $participant->contact_id
)));
1822 $actionSchedule = $this->fixtures
['sched_eventtype_start_1week_before'];
1823 $actionSchedule['entity_value'] = CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $participant->event_id
, 'event_type_id');
1824 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1826 //echo "CREATED\n"; ob_flush(); sleep(20);
1828 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1829 $this->assertCronRuns(array(
1832 'time' => '2012-03-02 01:00:00',
1833 'recipients' => array(),
1837 'time' => '2012-03-08 01:00:00',
1838 'recipients' => array(array('test-event@example.com')),
1841 // And then nothing else
1842 'time' => '2012-03-16 01:00:00',
1843 'recipients' => array(),
1848 public function testEventTypeEndDateRepeat() {
1849 // Create event+participant with start_date = 20120315, end_date = 20120615.
1850 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures
['participant'], array('status_id' => 2)));
1851 $this->callAPISuccess('Email', 'create', array(
1852 'contact_id' => $participant->contact_id
,
1853 'email' => 'test-event@example.com',
1855 $c = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures
['contact'], array('contact_id' => $participant->contact_id
)));
1857 $actionSchedule = $this->fixtures
['sched_eventtype_end_2month_repeat_twice_2_weeks'];
1858 $actionSchedule['entity_value'] = CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $participant->event_id
, 'event_type_id');
1859 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1861 $this->assertCronRuns(array(
1864 'time' => '2012-08-13 01:00:00',
1865 'recipients' => array(),
1868 // After the 2-month mark, send an email.
1869 'time' => '2012-08-16 01:00:00',
1870 'recipients' => array(array('test-event@example.com')),
1873 // After 2 months and 1 week, don't repeat yet.
1874 'time' => '2012-08-23 02:00:00',
1875 'recipients' => array(),
1878 // After 2 months and 2 weeks
1879 'time' => '2012-08-30 02:00:00',
1880 'recipients' => array(array('test-event@example.com')),
1883 // After 2 months and 4 week
1884 'time' => '2012-09-13 02:00:00',
1885 'recipients' => array(array('test-event@example.com')),
1888 // After 2 months and 6 weeks
1889 'time' => '2012-09-27 01:00:00',
1890 'recipients' => array(),
1895 // TODO // function testMembershipEndDate_NonMatch() { }
1896 // TODO // function testEventTypeStartDate_Match() { }
1897 // TODO // function testEventTypeEndDate_Match() { }
1898 // TODO // function testEventNameStartDate_Match() { }
1899 // TODO // function testEventNameEndDate_Match() { }
1902 * Run a series of cron jobs and make an assertion about email deliveries.
1904 * @param array $cronRuns
1905 * array specifying when to run cron and what messages to expect; each item is an array with keys:
1906 * - time: string, e.g. '2012-06-15 21:00:01'
1907 * - recipients: array(array(string)), list of email addresses which should receive messages
1909 public function assertCronRuns($cronRuns) {
1910 foreach ($cronRuns as $cronRun) {
1911 CRM_Utils_Time
::setTime($cronRun['time']);
1912 $this->callAPISuccess('job', 'send_reminder', array());
1913 $this->mut
->assertRecipients($cronRun['recipients']);
1914 if (array_key_exists('subjects', $cronRun)) {
1915 $this->mut
->assertSubjects($cronRun['subjects']);
1917 $this->mut
->clearMessages();
1922 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
1924 private $_testObjects;
1927 * Sets up the fixture, for example, opens a network connection.
1929 * This method is called before a test is executed.
1931 protected function _setUp() {
1932 $this->_testObjects
= array();
1936 * Tears down the fixture, for example, closes a network connection.
1938 * This method is called after a test is executed.
1940 protected function _tearDown() {
1942 $this->deleteTestObjects();
1946 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
1947 * created entities and provides for brainless cleanup.
1949 * @see CRM_Core_DAO::createTestObject
1952 * @param array $params
1953 * @param int $numObjects
1954 * @param bool $createOnly
1956 * @return array|NULL|object
1958 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
1959 $objects = CRM_Core_DAO
::createTestObject($daoName, $params, $numObjects, $createOnly);
1960 if (is_array($objects)) {
1961 $this->registerTestObjects($objects);
1964 $this->registerTestObjects(array($objects));
1970 * @param array $objects
1971 * DAO or BAO objects.
1973 public function registerTestObjects($objects) {
1974 //if (is_object($objects)) {
1975 // $objects = array($objects);
1977 foreach ($objects as $object) {
1978 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
1979 $this->_testObjects
[$daoName][] = $object->id
;
1983 public function deleteTestObjects() {
1984 // Note: You might argue that the FK relations between test
1985 // objects could make this problematic; however, it should
1986 // behave intuitively as long as we mentally split our
1987 // test-objects between the "manual/primary records"
1988 // and the "automatic/secondary records"
1989 foreach ($this->_testObjects
as $daoName => $daoIds) {
1990 foreach ($daoIds as $daoId) {
1991 CRM_Core_DAO
::deleteTestObjects($daoName, array('id' => $daoId));
1994 $this->_testObjects
= array();
1998 * Test that the various repetition units work correctly.
2001 public function testRepetitionFrequencyUnit() {
2002 $membershipTypeParams = array(
2003 'duration_interval' => '1',
2004 'duration_unit' => 'year',
2006 'period_type' => 'rolling',
2008 $membershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipTypeParams);
2009 $interval_units = array('hour', 'day', 'week', 'month', 'year');
2010 foreach ($interval_units as $interval_unit) {
2011 $membershipEndDate = DateTime
::createFromFormat('Y-m-d H:i:s', "2013-03-15 00:00:00");
2012 $contactParams = array(
2013 'contact_type' => 'Individual',
2014 'first_name' => 'Test',
2015 'last_name' => "Interval $interval_unit",
2018 $contact = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2019 $this->assertTrue(is_numeric($contact->id
));
2020 $emailParams = array(
2021 'contact_id' => $contact->id
,
2023 'email' => "test-member-{$interval_unit}@example.com",
2024 'location_type_id' => 1,
2026 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2027 $this->assertTrue(is_numeric($email->id
));
2028 $membershipParams = array(
2029 'membership_type_id' => $membershipType->id
,
2030 'contact_id' => $contact->id
,
2031 'join_date' => '20120315',
2032 'start_date' => '20120315',
2033 'end_date' => '20130315',
2037 $membershipParams['status-id'] = 1;
2038 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2039 $actionScheduleParams = $this->fixtures
['sched_on_membership_end_date_repeat_interval'];
2040 $actionScheduleParams['entity_value'] = $membershipType->id
;
2041 $actionScheduleParams['repetition_frequency_unit'] = $interval_unit;
2042 $actionScheduleParams['repetition_frequency_interval'] = 2;
2043 $actionSchedule = CRM_Core_BAO_ActionSchedule
::add($actionScheduleParams);
2044 $this->assertTrue(is_numeric($actionSchedule->id
));
2045 $beforeEndDate = $this->createModifiedDateTime($membershipEndDate, '-1 day');
2046 $beforeFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+1 $interval_unit");
2047 $afterFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+2 $interval_unit");
2050 'time' => $beforeEndDate->format('Y-m-d H:i:s'),
2051 'recipients' => array(),
2054 'time' => $membershipEndDate->format('Y-m-d H:i:s'),
2055 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2058 'time' => $beforeFirstUnit->format('Y-m-d H:i:s'),
2059 'recipients' => array(),
2062 'time' => $afterFirstUnit->format('Y-m-d H:i:s'),
2063 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2066 $this->assertCronRuns($cronRuns);
2067 $actionSchedule->delete();
2068 $membership->delete();
2073 * Inherited members without permission to edit the main member contact should
2074 * not get reminders.
2076 * However, just because a contact inherits one membership doesn't mean
2077 * reminders for other memberships should be suppressed.
2081 public function testInheritedMembershipPermissions() {
2082 // Set up common parameters for memberships.
2083 $membershipParams = $this->fixtures
['rolling_membership'];
2084 $membershipParams['status_id'] = 1;
2086 $membershipParams['membership_type_id']['relationship_type_id'] = 1;
2087 $membershipParams['membership_type_id']['relationship_direction'] = 'b_a';
2088 $membershipType1 = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipParams['membership_type_id']);
2090 // We'll create a new membership type that can be held at the same time as
2092 $membershipParams['membership_type_id']['relationship_type_id'] = 'NULL';
2093 $membershipParams['membership_type_id']['relationship_direction'] = 'NULL';
2094 $membershipType2 = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipParams['membership_type_id']);
2096 // Create the parent membership and contact
2097 $membershipParams['membership_type_id'] = $membershipType1->id
;
2098 $mainMembership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2101 'contact_type' => 'Individual',
2102 'first_name' => 'Mom',
2103 'last_name' => 'Rel',
2106 $this->createTestObject('CRM_Contact_DAO_Contact', array_merge($contactParams, ['id' => $mainMembership->contact_id
]));
2109 'contact_id' => $mainMembership->contact_id
,
2110 'email' => 'test-member@example.com',
2111 'location_type_id' => 1,
2114 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2116 // Set up contacts and emails for the two children
2117 $contactParams['first_name'] = 'Favorite';
2118 $permChild = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2119 $emailParams['email'] = 'favorite@example.com';
2120 $emailParams['contact_id'] = $permChild->id
;
2121 $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2123 $contactParams['first_name'] = 'Black Sheep';
2124 $nonPermChild = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2125 $emailParams['email'] = 'black.sheep@example.com';
2126 $emailParams['contact_id'] = $nonPermChild->id
;
2127 $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2129 // Each child gets a relationship, one with permission to edit the parent. This
2130 // will trigger inherited memberships for the first membership type
2132 'relationship_type_id' => 1,
2133 'contact_id_a' => $nonPermChild->id
,
2134 'contact_id_b' => $mainMembership->contact_id
,
2137 $this->callAPISuccess('relationship', 'create', $relParams);
2139 $relParams['contact_id_a'] = $permChild->id
;
2140 $relParams['is_permission_a_b'] = CRM_Contact_BAO_Relationship
::EDIT
;
2141 $this->callAPISuccess('relationship', 'create', $relParams);
2143 // Mom and Black Sheep get their own memberships of the second type.
2144 $membershipParams['membership_type_id'] = $membershipType2->id
;
2145 $membershipParams['owner_membership_id'] = 'NULL';
2146 $membershipParams['contact_id'] = $mainMembership->contact_id
;
2147 $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2149 $membershipParams['contact_id'] = $nonPermChild->id
;
2150 $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2152 // Test a reminder for the first membership type - that should exclude Black
2154 $actionSchedule = $this->fixtures
['sched_membership_join_2week'];
2155 $actionSchedule['entity_value'] = $membershipType1->id
;
2156 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
2157 $this->assertTrue(is_numeric($actionScheduleDao->id
));
2159 $this->assertCronRuns([
2161 'time' => '2012-03-29 01:00:00',
2162 'recipients' => [['test-member@example.com'], ['favorite@example.com']],
2164 'subject sched_membership_join_2week (joined March 15th, 2012)',
2165 'subject sched_membership_join_2week (joined March 15th, 2012)',
2170 // Test a reminder for the second membership type - that should include
2172 $actionSchedule = $this->fixtures
['sched_membership_start_1week'];
2173 $actionSchedule['entity_value'] = $membershipType2->id
;
2174 $actionScheduleDao = CRM_Core_BAO_ActionSchedule
::add($actionSchedule);
2175 $this->assertTrue(is_numeric($actionScheduleDao->id
));
2177 $this->assertCronRuns([
2179 'time' => '2012-03-22 01:00:00',
2180 'recipients' => [['test-member@example.com'], ['black.sheep@example.com']],
2182 'subject sched_membership_start_1week (joined March 15th, 2012)',
2183 'subject sched_membership_start_1week (joined March 15th, 2012)',
2189 public function createModifiedDateTime($origDateTime, $modifyRule) {
2190 $newDateTime = clone($origDateTime);
2191 $newDateTime->modify($modifyRule);
2192 return $newDateTime;