Merge pull request #14639 from colemanw/i18nCleanup
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / ActionScheduleTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035 27
e9479dcf
EM
28/**
29 * Class CRM_Core_BAO_ActionScheduleTest
2a21d018 30 * @group ActionSchedule
acb109b7 31 * @group headless
2a21d018
TO
32 *
33 * There are additional tests for some specific entities in other classes:
34 * @see CRM_Activity_ActionMappingTest
35 * @see CRM_Contribute_ActionMapping_ByTypeTest
e9479dcf 36 */
6a488035 37class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
63e9c3fd 38
6a488035 39 /**
f8c3594b 40 * @var CiviMailUtils
6a488035 41 */
567b2076 42 public $mut;
cee19268 43
00be9182 44 public function setUp() {
6a488035
TO
45 parent::setUp();
46
6c6e6187 47 $this->mut = new CiviMailUtils($this, TRUE);
6a488035 48
e08fae02
PH
49 $this->fixtures['rolling_membership_type'] = array(
50 'period_type' => 'rolling',
51 'duration_unit' => 'month',
52 'duration_interval' => '3',
53 'is_active' => 1,
54 'domain_id' => 1,
55 'financial_type_id' => 2,
56 );
57
57507ae6 58 $this->fixtures['rolling_membership'] = array(
6a488035
TO
59 'membership_type_id' => array(
60 'period_type' => 'rolling',
61 'duration_unit' => 'month',
62 'duration_interval' => '3',
63 'is_active' => 1,
64 ),
65 'join_date' => '20120315',
66 'start_date' => '20120315',
67 'end_date' => '20120615',
b29be8c2 68 'is_override' => 0,
6a488035 69 );
4b1efa1d 70
63e9c3fd 71 $this->fixtures['rolling_membership_past'] = array(
4b1efa1d 72 'membership_type_id' => array(
73 'period_type' => 'rolling',
74 'duration_unit' => 'month',
75 'duration_interval' => '3',
76 'is_active' => 1,
77 ),
78 'join_date' => '20100310',
79 'start_date' => '20100310',
80 'end_date' => '20100610',
81 'is_override' => 'NULL',
82 );
d3eae6ea
TO
83 $this->fixtures['participant'] = array(
84 'event_id' => array(
85 'is_active' => 1,
86 'is_template' => 0,
87 'title' => 'Example Event',
88 'start_date' => '20120315',
89 'end_date' => '20120615',
90 ),
39b959db
SL
91 // Attendee.
92 'role_id' => '1',
93 // No-show.
94 'status_id' => '8',
d3eae6ea 95 );
fe265b4e 96
db7de9c1 97 $this->fixtures['phonecall'] = array(
6a488035
TO
98 'status_id' => 1,
99 'activity_type_id' => 2,
100 'activity_date_time' => '20120615100000',
101 'is_current_revision' => 1,
102 'is_deleted' => 0,
103 );
db7de9c1 104 $this->fixtures['contact'] = array(
b29be8c2 105 'is_deceased' => 0,
6a488035
TO
106 'contact_type' => 'Individual',
107 'email' => 'test-member@example.com',
43ceab3f 108 'gender_id' => 'Female',
bba4f3f6
CB
109 'first_name' => 'Churmondleia',
110 'last_name' => 'Ōtākou',
6a488035 111 );
e08fae02
PH
112 $this->fixtures['contact_2'] = array(
113 'is_deceased' => 0,
114 'contact_type' => 'Individual',
115 'email' => 'test-contact-2@example.com',
116 'gender_id' => 'Male',
117 'first_name' => 'Fabble',
118 'last_name' => 'Fi',
119 );
db7de9c1 120 $this->fixtures['contact_birthdate'] = array(
43030baf
AH
121 'is_deceased' => 0,
122 'contact_type' => 'Individual',
123 'email' => 'test-bday@example.com',
124 'birth_date' => '20050707',
125 );
db7de9c1 126 $this->fixtures['sched_activity_1day'] = array(
6a488035
TO
127 'name' => 'One_Day_Phone_Call_Notice',
128 'title' => 'One Day Phone Call Notice',
84a3e359 129 'limit_to' => '1',
6a488035 130 'absolute_date' => NULL,
d19632b1
JP
131 'body_html' => '<p>1-Day (non-repeating) (for {activity.subject})</p>',
132 'body_text' => '1-Day (non-repeating) (for {activity.subject})',
6a488035
TO
133 'end_action' => NULL,
134 'end_date' => NULL,
135 'end_frequency_interval' => NULL,
136 'end_frequency_unit' => NULL,
137 'entity_status' => '1',
138 'entity_value' => '2',
139 'group_id' => NULL,
140 'is_active' => '1',
141 'is_repeat' => '0',
142 'mapping_id' => '1',
143 'msg_template_id' => NULL,
144 'recipient' => '2',
145 'recipient_listing' => NULL,
146 'recipient_manual' => NULL,
d19632b1 147 'record_activity' => 1,
6a488035
TO
148 'repetition_frequency_interval' => NULL,
149 'repetition_frequency_unit' => NULL,
150 'start_action_condition' => 'before',
151 'start_action_date' => 'activity_date_time',
152 'start_action_offset' => '1',
153 'start_action_unit' => 'day',
f8c3594b 154 'subject' => '1-Day (non-repeating) (about {activity.activity_type})',
6a488035
TO
155 );
156 $this->fixtures['sched_activity_1day_r'] = array(
157 'name' => 'One_Day_Phone_Call_Notice_R',
158 'title' => 'One Day Phone Call Notice R',
84a3e359 159 'limit_to' => 1,
6a488035
TO
160 'absolute_date' => NULL,
161 'body_html' => '<p>1-Day (repeating)</p>',
162 'body_text' => '1-Day (repeating)',
163 'end_action' => 'after',
164 'end_date' => 'activity_date_time',
165 'end_frequency_interval' => '2',
166 'end_frequency_unit' => 'day',
167 'entity_status' => '1',
168 'entity_value' => '2',
169 'group_id' => NULL,
170 'is_active' => '1',
171 'is_repeat' => '1',
172 'mapping_id' => '1',
173 'msg_template_id' => NULL,
174 'recipient' => '2',
175 'recipient_listing' => NULL,
176 'recipient_manual' => NULL,
177 'record_activity' => NULL,
178 'repetition_frequency_interval' => '6',
179 'repetition_frequency_unit' => 'hour',
180 'start_action_condition' => 'before',
181 'start_action_date' => 'activity_date_time',
182 'start_action_offset' => '1',
183 'start_action_unit' => 'day',
f8c3594b 184 'subject' => '1-Day (repeating) (about {activity.activity_type})',
6a488035 185 );
dc6c330d 186 $this->fixtures['sched_activity_1day_r_on_abs_date'] = array(
187 'name' => 'One_Day_Phone_Call_Notice_R',
188 'title' => 'One Day Phone Call Notice R',
189 'limit_to' => 1,
190 'absolute_date' => CRM_Utils_Date::processDate('20120614100000'),
191 'body_html' => '<p>1-Day (repeating)</p>',
192 'body_text' => '1-Day (repeating)',
193 'entity_status' => '1',
194 'entity_value' => '2',
195 'group_id' => NULL,
196 'is_active' => '1',
197 'is_repeat' => '1',
198 'mapping_id' => '1',
199 'msg_template_id' => NULL,
200 'recipient' => '2',
201 'recipient_listing' => NULL,
202 'recipient_manual' => NULL,
203 'record_activity' => NULL,
204 'repetition_frequency_interval' => '6',
205 'repetition_frequency_unit' => 'hour',
206 'end_action' => 'after',
207 'end_date' => 'activity_date_time',
208 'end_frequency_interval' => '2',
209 'end_frequency_unit' => 'day',
210 'start_action_condition' => '',
211 'start_action_date' => '',
212 'start_action_offset' => '',
213 'start_action_unit' => '',
214 'subject' => '1-Day (repeating) (about {activity.activity_type})',
215 );
e08fae02
PH
216 $this->fixtures['sched_eventname_1day_on_abs_date'] = array(
217 'name' => 'sched_eventname_1day_on_abs_date',
218 'title' => 'sched_eventname_1day_on_abs_date',
219 'limit_to' => 1,
220 'absolute_date' => CRM_Utils_Date::processDate('20120614100000'),
221 'body_html' => '<p>sched_eventname_1day_on_abs_date</p>',
222 'body_text' => 'sched_eventname_1day_on_abs_date',
223 'entity_status' => '1',
224 'entity_value' => '2',
225 'group_id' => NULL,
226 'is_active' => '1',
227 'is_repeat' => '0',
228 'mapping_id' => '3',
229 'msg_template_id' => NULL,
230 'recipient' => '2',
231 'recipient_listing' => NULL,
232 'recipient_manual' => NULL,
233 'record_activity' => NULL,
234 'repetition_frequency_interval' => NULL,
235 'repetition_frequency_unit' => NULL,
236 'end_action' => NULL,
237 'end_date' => NULL,
238 'end_frequency_interval' => NULL,
239 'end_frequency_unit' => NULL,
240 'start_action_condition' => NULL,
241 'start_action_date' => NULL,
242 'start_action_offset' => NULL,
243 'start_action_unit' => NULL,
244 'subject' => 'sched_eventname_1day_on_abs_date',
245 );
567b2076 246 $this->fixtures['sched_membership_join_2week'] = array(
6a488035
TO
247 'name' => 'sched_membership_join_2week',
248 'title' => 'sched_membership_join_2week',
249 'absolute_date' => '',
250 'body_html' => '<p>body sched_membership_join_2week</p>',
251 'body_text' => 'body sched_membership_join_2week',
252 'end_action' => '',
253 'end_date' => '',
254 'end_frequency_interval' => '',
255 'end_frequency_unit' => '',
256 'entity_status' => '',
257 'entity_value' => '',
258 'group_id' => '',
259 'is_active' => 1,
260 'is_repeat' => '0',
261 'mapping_id' => 4,
262 'msg_template_id' => '',
263 'recipient' => '',
264 'recipient_listing' => '',
265 'recipient_manual' => '',
266 'record_activity' => 1,
267 'repetition_frequency_interval' => '',
268 'repetition_frequency_unit' => '',
269 'start_action_condition' => 'after',
270 'start_action_date' => 'membership_join_date',
271 'start_action_offset' => '2',
272 'start_action_unit' => 'week',
f8c3594b 273 'subject' => 'subject sched_membership_join_2week (joined {membership.join_date})',
6a488035 274 );
bb3ba83e
AH
275 $this->fixtures['sched_membership_start_1week'] = array(
276 'name' => 'sched_membership_start_1week',
277 'title' => 'sched_membership_start_1week',
278 'absolute_date' => '',
279 'body_html' => '<p>body sched_membership_start_1week</p>',
280 'body_text' => 'body sched_membership_start_1week',
281 'end_action' => '',
282 'end_date' => '',
283 'end_frequency_interval' => '',
284 'end_frequency_unit' => '',
285 'entity_status' => '',
286 'entity_value' => '',
287 'group_id' => '',
288 'is_active' => 1,
289 'is_repeat' => '0',
290 'mapping_id' => 4,
291 'msg_template_id' => '',
292 'recipient' => '',
293 'recipient_listing' => '',
294 'recipient_manual' => '',
295 'record_activity' => 1,
296 'repetition_frequency_interval' => '',
297 'repetition_frequency_unit' => '',
298 'start_action_condition' => 'after',
299 'start_action_date' => 'membership_start_date',
300 'start_action_offset' => '1',
301 'start_action_unit' => 'week',
302 'subject' => 'subject sched_membership_start_1week (joined {membership.start_date})',
303 );
567b2076 304 $this->fixtures['sched_membership_end_2week'] = array(
6a488035
TO
305 'name' => 'sched_membership_end_2week',
306 'title' => 'sched_membership_end_2week',
307 'absolute_date' => '',
308 'body_html' => '<p>body sched_membership_end_2week</p>',
309 'body_text' => 'body sched_membership_end_2week',
310 'end_action' => '',
311 'end_date' => '',
312 'end_frequency_interval' => '',
313 'end_frequency_unit' => '',
314 'entity_status' => '',
315 'entity_value' => '',
316 'group_id' => '',
317 'is_active' => 1,
318 'is_repeat' => '0',
319 'mapping_id' => 4,
320 'msg_template_id' => '',
321 'recipient' => '',
322 'recipient_listing' => '',
323 'recipient_manual' => '',
324 'record_activity' => 1,
325 'repetition_frequency_interval' => '',
326 'repetition_frequency_unit' => '',
327 'start_action_condition' => 'before',
328 'start_action_date' => 'membership_end_date',
329 'start_action_offset' => '2',
330 'start_action_unit' => 'week',
331 'subject' => 'subject sched_membership_end_2week',
332 );
cbcb7579 333 $this->fixtures['sched_on_membership_end_date'] = array(
d2868251 334 'name' => 'sched_on_membership_end_date',
335 'title' => 'sched_on_membership_end_date',
336 'body_html' => '<p>Your membership expired today</p>',
337 'body_text' => 'Your membership expired today',
338 'is_active' => 1,
339 'mapping_id' => 4,
340 'record_activity' => 1,
341 'start_action_condition' => 'after',
342 'start_action_date' => 'membership_end_date',
343 'start_action_offset' => '0',
344 'start_action_unit' => 'hour',
345 'subject' => 'subject send reminder on membership_end_date',
346 );
cbcb7579 347 $this->fixtures['sched_after_1day_membership_end_date'] = array(
d2868251 348 'name' => 'sched_after_1day_membership_end_date',
349 'title' => 'sched_after_1day_membership_end_date',
350 'body_html' => '<p>Your membership expired yesterday</p>',
351 'body_text' => 'Your membership expired yesterday',
352 'is_active' => 1,
353 'mapping_id' => 4,
354 'record_activity' => 1,
355 'start_action_condition' => 'after',
356 'start_action_date' => 'membership_end_date',
357 'start_action_offset' => '1',
358 'start_action_unit' => 'day',
359 'subject' => 'subject send reminder on membership_end_date',
360 );
4b1efa1d 361
567b2076 362 $this->fixtures['sched_membership_end_2month'] = array(
4b1efa1d 363 'name' => 'sched_membership_end_2month',
364 'title' => 'sched_membership_end_2month',
365 'absolute_date' => '',
366 'body_html' => '<p>body sched_membership_end_2month</p>',
367 'body_text' => 'body sched_membership_end_2month',
368 'end_action' => '',
369 'end_date' => '',
370 'end_frequency_interval' => '',
371 'end_frequency_unit' => '',
372 'entity_status' => '',
373 'entity_value' => '',
374 'group_id' => '',
375 'is_active' => 1,
376 'is_repeat' => '0',
377 'mapping_id' => 4,
378 'msg_template_id' => '',
379 'recipient' => '',
380 'recipient_listing' => '',
381 'recipient_manual' => '',
382 'record_activity' => 1,
383 'repetition_frequency_interval' => '',
384 'repetition_frequency_unit' => '',
385 'start_action_condition' => 'after',
386 'start_action_date' => 'membership_end_date',
387 'start_action_offset' => '2',
388 'start_action_unit' => 'month',
389 'subject' => 'subject sched_membership_end_2month',
390 );
391
e08fae02
PH
392 $this->fixtures['sched_membership_absolute_date'] = array(
393 'name' => 'sched_membership_absolute_date',
394 'title' => 'sched_membership_absolute_date',
395 'absolute_date' => CRM_Utils_Date::processDate('20120614100000'),
396 'body_html' => '<p>body sched_membership_absolute_date</p>',
397 'body_text' => 'body sched_membership_absolute_date',
398 'end_action' => '',
399 'end_date' => '',
400 'end_frequency_interval' => '',
401 'end_frequency_unit' => '',
402 'entity_status' => '',
403 'entity_value' => '',
404 'group_id' => '',
405 'is_active' => 1,
406 'is_repeat' => '0',
407 'mapping_id' => 4,
408 'msg_template_id' => '',
409 'recipient' => '',
410 'recipient_listing' => '',
411 'recipient_manual' => '',
412 'record_activity' => 1,
413 'repetition_frequency_interval' => '',
414 'repetition_frequency_unit' => '',
415 'start_action_condition' => '',
416 'start_action_date' => '',
417 'start_action_offset' => '',
418 'start_action_unit' => '',
419 'subject' => 'subject sched_membership_absolute_date',
420 );
421
567b2076 422 $this->fixtures['sched_contact_bday_yesterday'] = array(
43030baf
AH
423 'name' => 'sched_contact_bday_yesterday',
424 'title' => 'sched_contact_bday_yesterday',
425 'absolute_date' => '',
426 'body_html' => '<p>you look like you were born yesterday!</p>',
427 'body_text' => 'you look like you were born yesterday!',
428 'end_action' => '',
429 'end_date' => '',
430 'end_frequency_interval' => '',
431 'end_frequency_unit' => '',
432 'entity_status' => 1,
433 'entity_value' => 'birth_date',
434 'group_id' => '',
435 'is_active' => 1,
436 'is_repeat' => '0',
437 'mapping_id' => 6,
438 'msg_template_id' => '',
439 'recipient' => '',
440 'recipient_listing' => '',
441 'recipient_manual' => '',
442 'record_activity' => 1,
443 'repetition_frequency_interval' => '',
444 'repetition_frequency_unit' => '',
445 'start_action_condition' => 'after',
446 'start_action_date' => 'date_field',
447 'start_action_offset' => '1',
448 'start_action_unit' => 'day',
449 'subject' => 'subject sched_contact_bday_yesterday',
450 );
451
567b2076 452 $this->fixtures['sched_contact_bday_anniv'] = array(
43030baf
AH
453 'name' => 'sched_contact_bday_anniv',
454 'title' => 'sched_contact_bday_anniv',
455 'absolute_date' => '',
456 'body_html' => '<p>happy birthday!</p>',
457 'body_text' => 'happy birthday!',
458 'end_action' => '',
459 'end_date' => '',
460 'end_frequency_interval' => '',
461 'end_frequency_unit' => '',
462 'entity_status' => 2,
463 'entity_value' => 'birth_date',
464 'group_id' => '',
465 'is_active' => 1,
466 'is_repeat' => '0',
467 'mapping_id' => 6,
468 'msg_template_id' => '',
469 'recipient' => '',
470 'recipient_listing' => '',
471 'recipient_manual' => '',
472 'record_activity' => 1,
473 'repetition_frequency_interval' => '',
474 'repetition_frequency_unit' => '',
475 'start_action_condition' => 'before',
476 'start_action_date' => 'date_field',
477 'start_action_offset' => '1',
478 'start_action_unit' => 'day',
479 'subject' => 'subject sched_contact_bday_anniv',
480 );
481
567b2076 482 $this->fixtures['sched_contact_grad_tomorrow'] = array(
43030baf
AH
483 'name' => 'sched_contact_grad_tomorrow',
484 'title' => 'sched_contact_grad_tomorrow',
485 'absolute_date' => '',
486 'body_html' => '<p>congratulations on your graduation!</p>',
487 'body_text' => 'congratulations on your graduation!',
488 'end_action' => '',
489 'end_date' => '',
490 'end_frequency_interval' => '',
491 'end_frequency_unit' => '',
492 'entity_status' => 1,
493 'group_id' => '',
494 'is_active' => 1,
495 'is_repeat' => '0',
496 'mapping_id' => 6,
497 'msg_template_id' => '',
498 'recipient' => '',
499 'recipient_listing' => '',
500 'recipient_manual' => '',
501 'record_activity' => 1,
502 'repetition_frequency_interval' => '',
503 'repetition_frequency_unit' => '',
504 'start_action_condition' => 'before',
505 'start_action_date' => 'date_field',
506 'start_action_offset' => '1',
507 'start_action_unit' => 'day',
508 'subject' => 'subject sched_contact_grad_tomorrow',
509 );
510
567b2076 511 $this->fixtures['sched_contact_grad_anniv'] = array(
43030baf
AH
512 'name' => 'sched_contact_grad_anniv',
513 'title' => 'sched_contact_grad_anniv',
514 'absolute_date' => '',
515 'body_html' => '<p>dear alum, please send us money.</p>',
516 'body_text' => 'dear alum, please send us money.',
517 'end_action' => '',
518 'end_date' => '',
519 'end_frequency_interval' => '',
520 'end_frequency_unit' => '',
521 'entity_status' => 2,
522 'group_id' => '',
523 'is_active' => 1,
524 'is_repeat' => '0',
525 'mapping_id' => 6,
526 'msg_template_id' => '',
527 'recipient' => '',
528 'recipient_listing' => '',
529 'recipient_manual' => '',
530 'record_activity' => 1,
531 'repetition_frequency_interval' => '',
532 'repetition_frequency_unit' => '',
533 'start_action_condition' => 'after',
534 'start_action_date' => 'date_field',
535 'start_action_offset' => '1',
536 'start_action_unit' => 'week',
537 'subject' => 'subject sched_contact_grad_anniv',
538 );
4aff0253
AH
539
540 $this->fixtures['sched_contact_created_yesterday'] = array(
541 'name' => 'sched_contact_created_yesterday',
542 'title' => 'sched_contact_created_yesterday',
543 'absolute_date' => '',
544 'body_html' => '<p>Your contact was created yesterday</p>',
545 'body_text' => 'Your contact was created yesterday!',
546 'end_action' => '',
547 'end_date' => '',
548 'end_frequency_interval' => '',
549 'end_frequency_unit' => '',
550 'entity_status' => 1,
551 'entity_value' => 'created_date',
552 'group_id' => '',
553 'is_active' => 1,
554 'is_repeat' => '0',
555 'mapping_id' => 6,
556 'msg_template_id' => '',
557 'recipient' => '',
558 'recipient_listing' => '',
559 'recipient_manual' => '',
560 'record_activity' => 1,
561 'repetition_frequency_interval' => '',
562 'repetition_frequency_unit' => '',
563 'start_action_condition' => 'after',
564 'start_action_date' => 'date_field',
565 'start_action_offset' => '1',
566 'start_action_unit' => 'day',
567 'subject' => 'subject sched_contact_created_yesterday',
568 );
569
570 $this->fixtures['sched_contact_mod_anniv'] = array(
571 'name' => 'sched_contact_mod_anniv',
572 'title' => 'sched_contact_mod_anniv',
573 'absolute_date' => '',
574 'body_html' => '<p>You last updated your data last year</p>',
575 'body_text' => 'Go update your stuff!',
576 'end_action' => '',
577 'end_date' => '',
578 'end_frequency_interval' => '',
579 'end_frequency_unit' => '',
580 'entity_status' => 2,
581 'entity_value' => 'modified_date',
582 'group_id' => '',
583 'is_active' => 1,
584 'is_repeat' => '0',
585 'mapping_id' => 6,
586 'msg_template_id' => '',
587 'recipient' => '',
588 'recipient_listing' => '',
589 'recipient_manual' => '',
590 'record_activity' => 1,
591 'repetition_frequency_interval' => '',
592 'repetition_frequency_unit' => '',
593 'start_action_condition' => 'before',
594 'start_action_date' => 'date_field',
595 'start_action_offset' => '1',
596 'start_action_unit' => 'day',
597 'subject' => 'subject sched_contact_mod_anniv',
598 );
599
d3eae6ea
TO
600 $this->fixtures['sched_eventtype_start_1week_before'] = array(
601 'name' => 'sched_eventtype_start_1week_before',
602 'title' => 'sched_eventtype_start_1week_before',
603 'absolute_date' => '',
604 'body_html' => '<p>body sched_eventtype_start_1week_before ({event.title})</p>',
605 'body_text' => 'body sched_eventtype_start_1week_before ({event.title})',
606 'end_action' => '',
607 'end_date' => '',
608 'end_frequency_interval' => '',
609 'end_frequency_unit' => '',
39b959db
SL
610 // participant status id
611 'entity_status' => '',
612 // event type id
613 'entity_value' => '',
d3eae6ea
TO
614 'group_id' => '',
615 'is_active' => 1,
616 'is_repeat' => '0',
39b959db
SL
617 // event type
618 'mapping_id' => 2,
d3eae6ea
TO
619 'msg_template_id' => '',
620 'recipient' => '',
621 'recipient_listing' => '',
622 'recipient_manual' => '',
623 'record_activity' => 1,
624 'repetition_frequency_interval' => '',
625 'repetition_frequency_unit' => '',
626 'start_action_condition' => 'before',
627 'start_action_date' => 'event_start_date',
628 'start_action_offset' => '1',
629 'start_action_unit' => 'week',
630 'subject' => 'subject sched_eventtype_start_1week_before ({event.title})',
631 );
632 $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'] = array(
633 'name' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
634 'title' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
635 'absolute_date' => '',
636 'body_html' => '<p>body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}</p>',
637 'body_text' => 'body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
638 'end_action' => 'after',
639 'end_date' => 'event_end_date',
640 'end_frequency_interval' => '3',
641 'end_frequency_unit' => 'month',
39b959db
SL
642 // participant status id
643 'entity_status' => '',
644 // event type id
645 'entity_value' => '',
d3eae6ea
TO
646 'group_id' => '',
647 'is_active' => 1,
648 'is_repeat' => '1',
39b959db
SL
649 // event type
650 'mapping_id' => 2,
d3eae6ea
TO
651 'msg_template_id' => '',
652 'recipient' => '',
653 'recipient_listing' => '',
654 'recipient_manual' => '',
655 'record_activity' => 1,
656 'repetition_frequency_interval' => '2',
657 'repetition_frequency_unit' => 'week',
658 'start_action_condition' => 'after',
659 'start_action_date' => 'event_end_date',
660 'start_action_offset' => '2',
661 'start_action_unit' => 'month',
662 'subject' => 'subject sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
663 );
664
567b2076 665 $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'] = array(
861d11c4
DG
666 'name' => 'sched_membership_end_2month',
667 'title' => 'sched_membership_end_2month',
668 'absolute_date' => '',
669 'body_html' => '<p>body sched_membership_end_2month</p>',
670 'body_text' => 'body sched_membership_end_2month',
671 'end_action' => '',
5c4d6559 672 'end_date' => 'membership_end_date',
861d11c4
DG
673 'end_frequency_interval' => '4',
674 'end_frequency_unit' => 'month',
675 'entity_status' => '',
676 'entity_value' => '',
677 'group_id' => '',
678 'is_active' => 1,
679 'is_repeat' => '1',
680 'mapping_id' => 4,
681 'msg_template_id' => '',
682 'recipient' => '',
683 'recipient_listing' => '',
684 'recipient_manual' => '',
685 'record_activity' => 1,
686 'repetition_frequency_interval' => '4',
687 'repetition_frequency_unit' => 'week',
688 'start_action_condition' => 'after',
689 'start_action_date' => 'membership_end_date',
690 'start_action_offset' => '2',
691 'start_action_unit' => 'month',
692 'subject' => 'subject sched_membership_end_2month',
693 );
567b2076 694 $this->fixtures['sched_membership_end_limit_to_none'] = array(
baa85770
EM
695 'name' => 'limit to none',
696 'title' => 'limit to none',
697 'absolute_date' => '',
698 'body_html' => '<p>body sched_membership_end_2month</p>',
699 'body_text' => 'body sched_membership_end_2month',
700 'end_action' => '',
701 'end_date' => '',
702 'end_frequency_interval' => '4',
703 'end_frequency_unit' => 'month',
704 'entity_status' => '',
705 'entity_value' => '',
706 'limit_to' => 0,
707 'group_id' => '',
708 'is_active' => 1,
709 'is_repeat' => '1',
710 'mapping_id' => 4,
711 'msg_template_id' => '',
712 'recipient' => '',
713 'recipient_listing' => '',
714 'recipient_manual' => '',
715 'record_activity' => 1,
716 'repetition_frequency_interval' => '4',
717 'repetition_frequency_unit' => 'week',
718 'start_action_condition' => 'after',
719 'start_action_date' => 'membership_end_date',
720 'start_action_offset' => '2',
721 'start_action_unit' => 'month',
722 'subject' => 'limit to none',
723 );
52f09320
PH
724 $this->fixtures['sched_on_membership_end_date_repeat_interval'] = array(
725 'name' => 'sched_on_membership_end_date',
726 'title' => 'sched_on_membership_end_date',
727 'body_html' => '<p>Your membership expired 1 unit ago</p>',
728 'body_text' => 'Your membership expired 1 unit ago',
729 'end_frequency_interval' => 10,
730 'end_frequency_unit' => 'year',
731 'is_active' => 1,
732 'is_repeat' => TRUE,
733 'mapping_id' => 4,
734 'record_activity' => 1,
735 'start_action_condition' => 'after',
736 'start_action_date' => 'membership_end_date',
737 'start_action_offset' => '0',
738 'start_action_unit' => 'hour',
739 'subject' => 'subject send reminder every unit after membership_end_date',
740 );
741
2273ddcb 742 $customGroup = $this->callAPISuccess('CustomGroup', 'create', array(
743 'title' => ts('Test Contact Custom group'),
744 'name' => 'test_contact_cg',
745 'extends' => 'Contact',
746 'domain_id' => CRM_Core_Config::domainID(),
747 'is_active' => 1,
748 'collapse_adv_display' => 0,
749 'collapse_display' => 0,
750 ));
751 $customField = $this->callAPISuccess('CustomField', 'create', array(
752 'label' => 'Test Text',
753 'data_type' => 'String',
754 'html_type' => 'Text',
755 'custom_group_id' => $customGroup['id'],
756 ));
757 $this->fixtures['contact_custom_token'] = array(
758 'id' => $customField['id'],
759 'token' => sprintf('{contact.custom_%s}', $customField['id']),
760 'name' => sprintf('custom_%s', $customField['id']),
761 'value' => 'text ' . substr(sha1(rand()), 0, 7),
762 );
763
6a488035 764 $this->_setUp();
6a488035
TO
765 }
766
767 /**
768 * Tears down the fixture, for example, closes a network connection.
92c99a4a 769 *
6a488035 770 * This method is called after a test is executed.
6a488035 771 */
00be9182 772 public function tearDown() {
6a488035 773 parent::tearDown();
6a488035
TO
774 $this->mut->clearMessages();
775 $this->mut->stop();
776 unset($this->mut);
92c99a4a
EM
777 $this->quickCleanup(array(
778 'civicrm_action_schedule',
779 'civicrm_action_log',
780 'civicrm_membership',
d3eae6ea
TO
781 'civicrm_participant',
782 'civicrm_event',
92c99a4a
EM
783 'civicrm_email',
784 ));
2273ddcb 785 $this->callAPISuccess('CustomField', 'delete', array('id' => $this->fixtures['contact_custom_token']['id']));
786 $this->callAPISuccess('CustomGroup', 'delete', array(
787 'id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', 'test_contact_cg', 'id', 'name'),
788 ));
6a488035
TO
789 $this->_tearDown();
790 }
791
43ceab3f
TO
792 public function mailerExamples() {
793 $cases = array();
794
bba4f3f6
CB
795 // Some tokens - short as subject has 128char limit in DB.
796 $someTokensTmpl = implode(';;', array(
39b959db
SL
797 // basic contact token
798 '{contact.display_name}',
799 // funny legacy contact token
800 '{contact.gender}',
801 // funny legacy contact token
802 '{contact.gender_id}',
803 // domain token
804 '{domain.name}',
805 // action-scheduler token
806 '{activity.activity_type}',
43ceab3f 807 ));
bba4f3f6
CB
808 // Further tokens can be tested in the body text/html.
809 $manyTokensTmpl = implode(';;', array(
810 $someTokensTmpl,
811 '{contact.email_greeting}',
2273ddcb 812 $this->fixture['contact_custom_token']['token'],
bba4f3f6 813 ));
ccdf6bd5
TO
814 // Note: The behavior of domain-tokens on a scheduled reminder is undefined. All we
815 // can really do is check that it has something.
bba4f3f6 816 $someTokensExpected = 'Churmondleia Ōtākou;;Female;;Female;;[a-zA-Z0-9 ]+;;Phone Call';
2273ddcb 817 $manyTokensExpected = sprintf('%s;;Dear Churmondleia;;%s', $someTokensExpected, $this->fixture['contact_custom_token']['value']);
43ceab3f 818
bba4f3f6 819 // In this example, we use a lot of tokens cutting across multiple components.
43ceab3f
TO
820 $cases[0] = array(
821 // Schedule definition.
822 array(
bba4f3f6 823 'subject' => "subj $someTokensTmpl",
43ceab3f
TO
824 'body_html' => "html $manyTokensTmpl",
825 'body_text' => "text $manyTokensTmpl",
826 ),
827 // Assertions (regex).
828 array(
829 'from_name' => "/^FIXME\$/",
830 'from_email' => "/^info@EXAMPLE.ORG\$/",
bba4f3f6 831 'subject' => "/^subj $someTokensExpected\$/",
43ceab3f
TO
832 'body_html' => "/^html $manyTokensExpected\$/",
833 'body_text' => "/^text $manyTokensExpected\$/",
834 ),
835 );
836
837 // In this example, we customize the from address.
838 $cases[1] = array(
839 // Schedule definition.
840 array(
841 'from_name' => 'Bob',
842 'from_email' => 'bob@example.org',
843 ),
844 // Assertions (regex).
845 array(
846 'from_name' => "/^Bob\$/",
847 'from_email' => "/^bob@example.org\$/",
848 ),
849 );
850
851 // In this example, we autoconvert HTML to text
852 $cases[2] = array(
853 // Schedule definition.
854 array(
855 'body_html' => '<p>Hello &amp; stuff.</p>',
856 'body_text' => '',
857 ),
858 // Assertions (regex).
859 array(
860 'body_html' => '/^' . preg_quote('<p>Hello &amp; stuff.</p>', '/') . '/',
861 'body_text' => '/^' . preg_quote('Hello & stuff.', '/') . '/',
862 ),
863 );
864
865 // In this example, we autoconvert HTML to text
866 $cases[3] = array(
867 // Schedule definition.
868 array(
869 'body_html' => '',
870 'body_text' => 'Hello world',
871 ),
872 // Assertions (regex).
873 array(
874 'body_html' => '/^--UNDEFINED--$/',
875 'body_text' => '/^Hello world$/',
876 ),
877 );
878
879 return $cases;
880 }
881
882 /**
883 * This generates a single mailing through the scheduled-reminder
884 * system (using an activity-reminder as a baseline) and
885 * checks that the resulting message satisfies various
886 * regular expressions.
887 *
888 * @param array $schedule
889 * Values to set/override in the schedule.
890 * Ex: array('subject' => 'Hello, {contact.first_name}!').
891 * @param array $patterns
892 * A list of regexes to compare with the actual email.
893 * Ex: array('subject' => '/^Hello, Alice!/').
894 * Keys: subject, body_text, body_html, from_name, from_email.
895 * @dataProvider mailerExamples
896 */
897 public function testMailer($schedule, $patterns) {
898 $actionSchedule = array_merge($this->fixtures['sched_activity_1day'], $schedule);
899 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
900 $this->assertTrue(is_numeric($actionScheduleDao->id));
901
902 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
903 $this->assertTrue(is_numeric($activity->id));
2273ddcb 904 $contact = $this->callAPISuccess('contact', 'create', array_merge(
905 $this->fixtures['contact'],
906 array(
907 $this->fixtures['contact_custom_token']['name'] => $this->fixtures['contact_custom_token']['value'],
908 )
909 ));
43ceab3f
TO
910 $activity->save();
911
912 $source['contact_id'] = $contact['id'];
913 $source['activity_id'] = $activity->id;
914 $source['record_type_id'] = 2;
915 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
916 $activityContact->save();
917
918 CRM_Utils_Time::setTime('2012-06-14 15:00:00');
919 $this->callAPISuccess('job', 'send_reminder', array());
920 $this->mut->assertRecipients(array(array('test-member@example.com')));
921 foreach ($this->mut->getAllMessages('ezc') as $message) {
922 /** @var ezcMail $message */
923
924 $messageArray = array();
925 $messageArray['subject'] = $message->subject;
926 $messageArray['from_name'] = $message->from->name;
927 $messageArray['from_email'] = $message->from->email;
928 $messageArray['body_text'] = '--UNDEFINED--';
929 $messageArray['body_html'] = '--UNDEFINED--';
930
931 foreach ($message->fetchParts() as $part) {
932 /** @var ezcMailText ezcMailText */
933 if ($part instanceof ezcMailText && $part->subType == 'html') {
934 $messageArray['body_html'] = $part->text;
935 }
936 if ($part instanceof ezcMailText && $part->subType == 'plain') {
937 $messageArray['body_text'] = $part->text;
938 }
939 }
940
941 foreach ($patterns as $field => $pattern) {
942 $this->assertRegExp($pattern, $messageArray[$field],
943 "Check that '$field'' matches regex. " . print_r(array('expected' => $patterns, 'actual' => $messageArray), 1));
944 }
945 }
946 $this->mut->clearMessages();
43ceab3f
TO
947 }
948
92c99a4a 949 public function testActivityDateTimeMatchNonRepeatableSchedule() {
cee19268 950 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day']);
6a488035
TO
951 $this->assertTrue(is_numeric($actionScheduleDao->id));
952
953 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
6a488035 954 $this->assertTrue(is_numeric($activity->id));
6c6e6187 955 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
d19632b1 956 $activity->subject = "Test subject for Phonecall";
6a488035
TO
957 $activity->save();
958
4f20f356 959 $source['contact_id'] = $contact['id'];
960 $source['activity_id'] = $activity->id;
961 $source['record_type_id'] = 2;
962 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
963 $activityContact->save();
964
6a488035 965 $this->assertCronRuns(array(
567b2076
EM
966 array(
967 // Before the 24-hour mark, no email
6a488035
TO
968 'time' => '2012-06-14 04:00:00',
969 'recipients' => array(),
f8c3594b 970 'subjects' => array(),
6a488035 971 ),
567b2076
EM
972 array(
973 // After the 24-hour mark, an email
6a488035
TO
974 'time' => '2012-06-14 15:00:00',
975 'recipients' => array(array('test-member@example.com')),
f8c3594b 976 'subjects' => array('1-Day (non-repeating) (about Phone Call)'),
6a488035 977 ),
567b2076
EM
978 array(
979 // Run cron again; message already sent
6a488035
TO
980 'time' => '',
981 'recipients' => array(),
982 ),
983 ));
d19632b1
JP
984 $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, FALSE, FALSE, 'name');
985 $activityDAO = new CRM_Activity_DAO_Activity();
986 $activityDAO->source_record_id = $activity->id;
987 $activityDAO->activity_type_id = array_search('Reminder Sent', $activityTypes);
988 $activityDAO->find();
989 while ($activityDAO->fetch()) {
990 $this->assertContains($activity->subject, $activityDAO->details);
991 }
6a488035
TO
992 }
993
92c99a4a 994 public function testActivityDateTimeMatchRepeatableSchedule() {
cee19268 995 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r']);
6a488035
TO
996 $this->assertTrue(is_numeric($actionScheduleDao->id));
997
998 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
999 $this->assertTrue(is_numeric($activity->id));
6c6e6187 1000 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
6a488035
TO
1001 $activity->save();
1002
4f20f356 1003 $source['contact_id'] = $contact['id'];
1004 $source['activity_id'] = $activity->id;
6c6e6187 1005 $source['record_type_id'] = 2;
4f20f356 1006 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
1007 $activityContact->save();
1008
6a488035 1009 $this->assertCronRuns(array(
567b2076
EM
1010 array(
1011 // Before the 24-hour mark, no email
6a488035
TO
1012 'time' => '012-06-14 04:00:00',
1013 'recipients' => array(),
f8c3594b 1014 'subjects' => array(),
6a488035 1015 ),
567b2076
EM
1016 array(
1017 // After the 24-hour mark, an email
6a488035
TO
1018 'time' => '2012-06-14 15:00:00',
1019 'recipients' => array(array('test-member@example.com')),
f8c3594b 1020 'subjects' => array('1-Day (repeating) (about Phone Call)'),
6a488035 1021 ),
567b2076
EM
1022 array(
1023 // Run cron 4 hours later; first message already sent
6a488035
TO
1024 'time' => '2012-06-14 20:00:00',
1025 'recipients' => array(),
f8c3594b 1026 'subjects' => array(),
6a488035 1027 ),
567b2076
EM
1028 array(
1029 // Run cron 6 hours later; send second message.
6a488035
TO
1030 'time' => '2012-06-14 21:00:01',
1031 'recipients' => array(array('test-member@example.com')),
f8c3594b 1032 'subjects' => array('1-Day (repeating) (about Phone Call)'),
6a488035
TO
1033 ),
1034 ));
1035 }
1036
dc6c330d 1037 public function testActivityDateTimeMatchRepeatableScheduleOnAbsDate() {
1038 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r_on_abs_date']);
1039 $this->assertTrue(is_numeric($actionScheduleDao->id));
1040
1041 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
1042 $this->assertTrue(is_numeric($activity->id));
1043 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
1044 $activity->save();
1045
1046 $source['contact_id'] = $contact['id'];
1047 $source['activity_id'] = $activity->id;
1048 $source['record_type_id'] = 2;
1049 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
1050 $activityContact->save();
1051
1052 $this->assertCronRuns(array(
1053 array(
1054 // Before the 24-hour mark, no email
1055 'time' => '2012-06-13 04:00:00',
1056 'recipients' => array(),
1057 'subjects' => array(),
1058 ),
1059 array(
1060 // On absolute date set on 2012-06-14
1061 'time' => '2012-06-14 00:00:00',
1062 'recipients' => array(array('test-member@example.com')),
1063 'subjects' => array('1-Day (repeating) (about Phone Call)'),
1064 ),
1065 array(
1066 // Run cron 4 hours later; first message already sent
1067 'time' => '2012-06-14 04:00:00',
1068 'recipients' => array(),
1069 'subjects' => array(),
1070 ),
1071 array(
1072 // Run cron 6 hours later; send second message.
1073 'time' => '2012-06-14 06:00:01',
1074 'recipients' => array(array('test-member@example.com')),
1075 'subjects' => array('1-Day (repeating) (about Phone Call)'),
1076 ),
1077 ));
1078 }
1079
e08fae02
PH
1080 public function testEventNameWithAbsoluteDateAndNothingElse() {
1081 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 1)));
1082 $this->callAPISuccess('Email', 'create', array(
1083 'contact_id' => $participant->contact_id,
1084 'email' => 'test-event@example.com',
1085 ));
1086 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1087
1088 $actionSchedule = $this->fixtures['sched_eventname_1day_on_abs_date'];
1089 $actionSchedule['entity_value'] = $participant->event_id;
1090 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1091
1092 $this->assertCronRuns(array(
1093 array(
1094 // Before the 24-hour mark, no email
1095 'time' => '2012-06-13 04:00:00',
1096 'recipients' => array(),
1097 'subjects' => array(),
1098 ),
1099 array(
1100 // On absolute date set on 2012-06-14
1101 'time' => '2012-06-14 00:00:00',
1102 'recipients' => array(array('test-event@example.com')),
1103 'subjects' => array('sched_eventname_1day_on_abs_date'),
1104 ),
1105 array(
1106 // Run cron 4 hours later; first message already sent
1107 'time' => '2012-06-14 04:00:00',
1108 'recipients' => array(),
1109 'subjects' => array(),
1110 ),
1111 ));
1112 }
1113
6a488035
TO
1114 /**
1115 * For contacts/activities which don't match the schedule filter,
1116 * an email should *not* be sent.
1117 */
1118 // TODO // function testActivityDateTime_NonMatch() { }
1119
1120 /**
76ea51c7 1121 * For contacts/members which match schedule based on join/start date,
6a488035
TO
1122 * an email should be sent.
1123 */
76ea51c7 1124 public function testMembershipDateMatch() {
bb3ba83e
AH
1125 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
1126 $this->assertTrue(is_numeric($membership->id));
1127 $result = $this->callAPISuccess('Email', 'create', array(
1128 'contact_id' => $membership->contact_id,
1129 'email' => 'test-member@example.com',
1130 'location_type_id' => 1,
1131 'is_primary' => 1,
1132 ));
6a488035 1133
bb3ba83e
AH
1134 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1135 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1136 $actionSchedule['entity_value'] = $membership->membership_type_id;
1137 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1138 $this->assertTrue(is_numeric($actionScheduleDao->id));
6a488035 1139
bb3ba83e
AH
1140 // start_date=2012-03-15 ; schedule is 2 weeks after join_date
1141 $this->assertCronRuns(array(
1142 array(
1143 // Before the 2-week mark, no email.
1144 'time' => '2012-03-28 01:00:00',
1145 'recipients' => array(),
1146 'subjects' => array(),
1147 ),
1148 array(
1149 // After the 2-week mark, send an email.
1150 'time' => '2012-03-29 01:00:00',
1151 'recipients' => array(array('test-member@example.com')),
1152 'subjects' => array('subject sched_membership_join_2week (joined March 15th, 2012)'),
1153 ),
1154 ));
1155
1156 $actionSchedule = $this->fixtures['sched_membership_start_1week'];
1157 $actionSchedule['entity_value'] = $membership->membership_type_id;
1158 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1159 $this->assertTrue(is_numeric($actionScheduleDao->id));
1160
1161 // start_date=2012-03-15 ; schedule is 1 weeks after start_date
1162 $this->assertCronRuns(array(
1163 array(
1164 // Before the 2-week mark, no email.
1165 'time' => '2012-03-21 01:00:00',
1166 'recipients' => array(),
1167 'subjects' => array(),
1168 ),
1169 array(
1170 // After the 2-week mark, send an email.
1171 'time' => '2012-03-22 01:00:00',
1172 'recipients' => array(array('test-member@example.com')),
1173 'subjects' => array('subject sched_membership_start_1week (joined March 15th, 2012)'),
1174 ),
1175 ));
6a488035
TO
1176 }
1177
cc949606 1178 /**
1179 * CRM-21675: Support parent and smart group in 'Limit to' field
1180 */
1181 public function testScheduleReminderWithParentGroup() {
1182 // Contact A with birth-date at '07-07-2005' and gender - Male, later got added in smart group
1183 $contactID1 = $this->individualCreate(array('birth_date' => '20050707', 'gender_id' => 1, 'email' => 'abc@test.com'));
1184 // Contact B with birth-date at '07-07-2005', later got added in regular group
1185 $contactID2 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'def@test.com'), 1);
1186 // Contact C with birth-date at '07-07-2005', but not included in any group
1187 $contactID3 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'ghi@test.com'), 2);
1188
1189 // create regular group and add Contact B to it
1190 $groupID = $this->groupCreate();
1191 $this->callAPISuccess('GroupContact', 'Create', array(
1192 'group_id' => $groupID,
1193 'contact_id' => $contactID2,
1194 ));
1195
1196 // create smart group which will contain all Male contacts
1197 $smartGroupParams = array('formValues' => array('gender_id' => 1));
1198 $smartGroupID = $this->smartGroupCreate(
1199 $smartGroupParams,
1200 array(
1201 'name' => 'new_smart_group',
1202 'title' => 'New Smart Group',
1203 'parents' => array($groupID => 1),
1204 )
1205 );
1206
1207 $actionScheduleParams = array(
1208 'name' => 'sched_contact_bday_yesterday',
1209 'title' => 'sched_contact_bday_yesterday',
1210 'absolute_date' => '',
1211 'body_html' => '<p>you look like you were born yesterday!</p>',
1212 'body_text' => 'you look like you were born yesterday!',
1213 'end_action' => '',
1214 'end_date' => '',
1215 'end_frequency_interval' => '',
1216 'end_frequency_unit' => '',
1217 'entity_status' => 1,
1218 'entity_value' => 'birth_date',
1219 'limit_to' => 1,
1220 'group_id' => $groupID,
1221 'is_active' => 1,
1222 'is_repeat' => '0',
1223 'mapping_id' => 6,
1224 'msg_template_id' => '',
1225 'recipient' => '2',
1226 'recipient_listing' => '',
1227 'recipient_manual' => '',
1228 'record_activity' => 1,
1229 'repetition_frequency_interval' => '',
1230 'repetition_frequency_unit' => '',
1231 'start_action_condition' => 'after',
1232 'start_action_date' => 'date_field',
1233 'start_action_offset' => '1',
1234 'start_action_unit' => 'day',
1235 'subject' => 'subject sched_contact_bday_yesterday',
1236 );
1237
1238 // Create schedule reminder where parent group ($groupID) is selectd to limit recipients,
1239 // which contain a individual contact - $contactID2 and is parent to smart group.
1240 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
1241 $this->assertTrue(is_numeric($actionScheduleDao->id));
1242 $this->assertCronRuns(array(
1243 array(
1244 // On the birthday, no email.
1245 'time' => '2005-07-07 01:00:00',
1246 'recipients' => array(),
1247 ),
1248 array(
1249 // The next day, send an email.
1250 'time' => '2005-07-08 20:00:00',
1251 'recipients' => array(
1252 array(
1253 'def@test.com',
1254 ),
1255 array(
1256 'abc@test.com',
1257 ),
1258 ),
1259 ),
1260 ));
1261 $this->groupDelete($smartGroupID);
1262 $this->groupDelete($groupID);
1263 }
1264
6a488035 1265 /**
442cf836
EM
1266 * Test end date email sent.
1267 *
6a488035
TO
1268 * For contacts/members which match schedule based on join date,
1269 * an email should be sent.
1270 */
92c99a4a 1271 public function testMembershipJoinDateNonMatch() {
6a488035
TO
1272 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures['rolling_membership']);
1273 $this->assertTrue(is_numeric($membership->id));
bf308d29 1274 $result = $this->callAPISuccess('Email', 'create', array(
6a488035
TO
1275 'contact_id' => $membership->contact_id,
1276 'location_type_id' => 1,
1277 'email' => 'test-member@example.com',
6a488035 1278 ));
fe265b4e 1279
6a488035
TO
1280 // Add an alternative membership type, and only send messages for that type
1281 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
1282 $this->assertTrue(is_numeric($extraMembershipType->id));
cee19268 1283 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_membership_join_2week']);
6a488035
TO
1284 $this->assertTrue(is_numeric($actionScheduleDao->id));
1285 $actionScheduleDao->entity_value = $extraMembershipType->id;
1286 $actionScheduleDao->save();
1287
1288 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1289 $this->assertCronRuns(array(
567b2076
EM
1290 array(
1291 // After the 2-week mark, don't send email because we have different membership type.
6a488035
TO
1292 'time' => '2012-03-29 01:00:00',
1293 'recipients' => array(),
1294 ),
1295 ));
1296 }
1297
861d11c4 1298 /**
442cf836 1299 * Test that the first and SECOND notifications are sent out.
861d11c4 1300 */
92c99a4a 1301 public function testMembershipEndDateRepeat() {
861d11c4
DG
1302 // creates membership with end_date = 20120615
1303 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1304 $result = $this->callAPISuccess('Email', 'create', array(
1305 'contact_id' => $membership->contact_id,
1306 'email' => 'test-member@example.com',
1307 ));
1308 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1309
1310 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1311 $actionSchedule['entity_value'] = $membership->membership_type_id;
1312 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1313
1314 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1315 $this->assertCronRuns(array(
567b2076 1316 array(
e08fae02
PH
1317 // After the 1-month mark, no email
1318 'time' => '2012-07-15 01:00:00',
1319 'recipients' => array(),
1320 ),
1321 array(
1322 // After the 2-month mark, send an email.
861d11c4
DG
1323 'time' => '2012-08-15 01:00:00',
1324 'recipients' => array(array('test-member@example.com')),
1325 ),
567b2076 1326 array(
e08fae02 1327 // 4 weeks after first email send first repeat
861d11c4
DG
1328 'time' => '2012-09-12 01:00:00',
1329 'recipients' => array(array('test-member@example.com')),
1330 ),
e08fae02
PH
1331 array(
1332 // 1 week after first repeat send nothing
1333 // There was a bug where the first repeat went out and then
1334 // it would keep going out every cron run. This is to check that's
1335 // not happening.
1336 'time' => '2012-09-19 01:00:00',
1337 'recipients' => array(),
1338 ),
1339 array(
1340 // 4 weeks after first repeat send second repeat
1341 'time' => '2012-10-10 01:00:00',
1342 'recipients' => array(array('test-member@example.com')),
1343 ),
1344 array(
1345 // 4 months after membership end, send nothing
1346 'time' => '2012-10-15 01:00:00',
1347 'recipients' => array(),
1348 ),
1349 array(
1350 // 5 months after membership end, send nothing
1351 'time' => '2012-11-15 01:00:00',
1352 'recipients' => array(),
1353 ),
861d11c4
DG
1354 ));
1355 }
1356
1357 /**
442cf836
EM
1358 * Test behaviour when date changes.
1359 *
861d11c4
DG
1360 * Test that the first notification is sent but the second is NOT sent if the end date changes in
1361 * between
1362 * see CRM-15376
1363 */
92c99a4a 1364 public function testMembershipEndDateRepeatChangedEndDate_CRM_15376() {
861d11c4
DG
1365 // creates membership with end_date = 20120615
1366 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1367 $this->callAPISuccess('Email', 'create', array(
1368 'contact_id' => $membership->contact_id,
1369 'email' => 'test-member@example.com',
1370 ));
1371 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1372
1373 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1374 $actionSchedule['entity_value'] = $membership->membership_type_id;
1375 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1376 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1377 $this->assertCronRuns(array(
567b2076
EM
1378 array(
1379 // After the 2-week mark, send an email.
861d11c4
DG
1380 'time' => '2012-08-15 01:00:00',
1381 'recipients' => array(array('test-member@example.com')),
1382 ),
1383 ));
1384
442cf836 1385 // Extend membership - reminder should NOT go out.
861d11c4
DG
1386 $this->callAPISuccess('membership', 'create', array('id' => $membership->id, 'end_date' => '2014-01-01'));
1387 $this->assertCronRuns(array(
442cf836
EM
1388 array(
1389 // After the 2-week mark, send an email.
861d11c4
DG
1390 'time' => '2012-09-12 01:00:00',
1391 'recipients' => array(),
1392 ),
1393 ));
1394 }
1395
6a488035 1396 /**
442cf836
EM
1397 * Test membership end date email sends.
1398 *
6a488035
TO
1399 * For contacts/members which match schedule based on end date,
1400 * an email should be sent.
1401 */
92c99a4a 1402 public function testMembershipEndDateMatch() {
6a488035 1403 // creates membership with end_date = 20120615
b29be8c2 1404 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
6a488035 1405 $this->assertTrue(is_numeric($membership->id));
bf308d29 1406 $this->callAPISuccess('Email', 'create', array(
6a488035
TO
1407 'contact_id' => $membership->contact_id,
1408 'email' => 'test-member@example.com',
92915c55 1409 ));
bf308d29 1410 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
6a488035
TO
1411
1412 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
1413 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 1414 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
6a488035
TO
1415 $this->assertTrue(is_numeric($actionScheduleDao->id));
1416
1417 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1418 $this->assertCronRuns(array(
442cf836
EM
1419 array(
1420 // Before the 2-week mark, no email.
6a488035 1421 'time' => '2012-05-31 01:00:00',
6a488035
TO
1422 'recipients' => array(),
1423 ),
442cf836
EM
1424 array(
1425 // After the 2-week mark, send an email.
6a488035
TO
1426 'time' => '2012-06-01 01:00:00',
1427 'recipients' => array(array('test-member@example.com')),
1428 ),
e08fae02
PH
1429 array(
1430 // After the email is sent, another one is not sent
1431 'time' => '2012-06-01 02:00:00',
1432 'recipients' => array(),
1433 ),
6a488035 1434 ));
d2868251 1435
1436 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
1437 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
1438 $membership->end_date = '2012-09-15';
1439 $membership->save();
1440
1441 //change the email id of chosen membership contact to assert
1442 //recipient of not the previously sent mail but the new one
1443 $result = $this->callAPISuccess('Email', 'create', array(
1444 'is_primary' => 1,
1445 'contact_id' => $membership->contact_id,
cbcb7579 1446 'email' => 'member2@example.com',
d2868251 1447 ));
1448 $this->assertAPISuccess($result);
1449
1450 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
1451 $this->assertCronRuns(array(
cbcb7579
TO
1452 array(
1453 // Before the 2-week mark, no email
d2868251 1454 'time' => '2012-08-31 01:00:00',
1455 'recipients' => array(),
cbcb7579 1456 ),
e08fae02
PH
1457 array(
1458 // After the 2-week mark, send an email
1459 'time' => '2012-09-01 01:00:00',
1460 'recipients' => array(array('member2@example.com')),
1461 ),
1462 array(
1463 // After the email is sent, another one is not sent
1464 'time' => '2012-09-01 02:00:00',
1465 'recipients' => array(),
1466 ),
1467 ));
1468
1469 $membership->end_date = '2012-12-15';
1470 $membership->save();
1471 // end_date=2012-12-15 ; schedule is 2 weeks before end_date
1472 $this->assertCronRuns(array(
1473 array(
1474 // Before the 2-week mark, no email
1475 'time' => '2012-11-30 01:00:00',
1476 'recipients' => array(),
1477 ),
1478 array(
1479 // After the 2-week mark, send an email
1480 'time' => '2012-12-01 01:00:00',
1481 'recipients' => array(array('member2@example.com')),
1482 ),
1483 array(
1484 // After the email is sent, another one is not sent
1485 'time' => '2012-12-01 02:00:00',
1486 'recipients' => array(),
1487 ),
1488 ));
1489
1490 }
1491
1492 public function createMembershipAndContact($contactFixture, $membershipTypeId) {
1493 $result = $this->callAPISuccess('contact', 'create', $contactFixture);
1494 $contact = $result['values'][$result['id']];
1495 $params = array(
1496 'status_id' => 2,
1497 'contact_id' => $contact['id'],
1498 'membership_type_id' => $membershipTypeId,
1499 'owner_membership_id' => 'NULL',
1500 );
1501 $params = array_merge($this->fixtures['rolling_membership'], $params);
1502 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $params);
1503 $this->assertTrue(is_numeric($membership->id));
1504 return $membership;
1505 }
1506
1507 /**
1508 * This test is very similar to testMembershipEndDateMatch, but it adds
1509 * another contact because there was a bug in
1510 * RecipientBuilder::buildRelFirstPass where it was only sending the
1511 * reminder for the first contact returned in a query for renewed
1512 * memberships. Other contacts wouldn't get the mail.
1513 */
1514 public function testMultipleMembershipEndDateMatch() {
1515 $membershipTypeId = $this->membershipTypeCreate($this->fixtures['rolling_membership']['membership_type_id']);
1516 $membershipOne = $this->createMembershipAndContact($this->fixtures['contact'], $membershipTypeId);
1517 $membershipTwo = $this->createMembershipAndContact($this->fixtures['contact_2'], $membershipTypeId);
1518 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
1519 $actionSchedule['entity_value'] = $membershipTypeId;
1520 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1521 $this->assertTrue(is_numeric($actionScheduleDao->id));
1522
1523 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1524 $this->assertCronRuns(array(
1525 array(
1526 // Before the 2-week mark, no email.
1527 'time' => '2012-05-31 01:00:00',
1528 'recipients' => array(),
1529 ),
1530 array(
1531 // After the 2-week mark, send emails.
1532 'time' => '2012-06-01 01:00:00',
1533 'recipients' => array(
1534 array('test-member@example.com'),
1535 array('test-contact-2@example.com'),
1536 ),
1537 ),
1538 array(
1539 // After the email is sent, another one is not sent
1540 'time' => '2012-06-01 02:00:00',
1541 'recipients' => array(),
1542 ),
1543 ));
1544
1545 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
1546 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
1547 $membershipOne->end_date = '2012-09-15';
1548 $membershipOne->save();
1549 $membershipTwo->end_date = '2012-09-15';
1550 $membershipTwo->save();
1551
1552 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
1553 $this->assertCronRuns(array(
1554 array(
1555 // Before the 2-week mark, no email
1556 'time' => '2012-08-31 01:00:00',
1557 'recipients' => array(),
1558 ),
1559 array(
1560 // After the 2-week mark, send an email
1561 'time' => '2012-09-01 01:00:00',
1562 'recipients' => array(
1563 array('test-member@example.com'),
1564 array('test-contact-2@example.com'),
1565 ),
1566 ),
1567 array(
1568 // After the email is sent, another one is not sent
1569 'time' => '2012-06-01 02:00:00',
1570 'recipients' => array(),
1571 ),
d2868251 1572 ));
6a488035
TO
1573 }
1574
4b1efa1d 1575 /**
442cf836
EM
1576 * Test membership end date email.
1577 *
6c6e6187
TO
1578 * For contacts/members which match schedule based on end date,
1579 * an email should be sent.
1580 */
92c99a4a 1581 public function testMembershipEndDateNoMatch() {
4b1efa1d 1582 // creates membership with end_date = 20120615
5c4d6559 1583 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 3)));
4b1efa1d 1584 $this->assertTrue(is_numeric($membership->id));
6c6e6187 1585 $result = $this->callAPISuccess('Email', 'create', array(
4b1efa1d 1586 'contact_id' => $membership->contact_id,
1587 'email' => 'test-member@example.com',
4b1efa1d 1588 ));
bf308d29 1589 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
4b1efa1d 1590
1591 $actionSchedule = $this->fixtures['sched_membership_end_2month'];
1592 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 1593 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
4b1efa1d 1594 $this->assertTrue(is_numeric($actionScheduleDao->id));
1595
1596 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1597 $this->assertCronRuns(array(
442cf836
EM
1598 array(
1599 // Before the 2-week mark, no email.
4b1efa1d 1600 'time' => '2012-05-31 01:00:00',
4b1efa1d 1601 'recipients' => array(),
1602 ),
442cf836 1603 array(
e08fae02 1604 // After the 2-week mark, no email
4b1efa1d 1605 'time' => '2013-05-01 01:00:00',
1606 'recipients' => array(),
1607 ),
1608 ));
1609 }
1610
92c99a4a 1611 public function testContactBirthDateNoAnniv() {
bf308d29 1612 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
1613 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1614 $actionSchedule = $this->fixtures['sched_contact_bday_yesterday'];
1615 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1616 $this->assertTrue(is_numeric($actionScheduleDao->id));
1617 $this->assertCronRuns(array(
442cf836
EM
1618 array(
1619 // On the birthday, no email.
43030baf
AH
1620 'time' => '2005-07-07 01:00:00',
1621 'recipients' => array(),
1622 ),
442cf836
EM
1623 array(
1624 // The next day, send an email.
43030baf
AH
1625 'time' => '2005-07-08 20:00:00',
1626 'recipients' => array(array('test-bday@example.com')),
1627 ),
1628 ));
1629 }
1630
92c99a4a 1631 public function testContactBirthDateAnniversary() {
6c6e6187 1632 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
1633 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1634 $actionSchedule = $this->fixtures['sched_contact_bday_anniv'];
1635 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1636 $this->assertTrue(is_numeric($actionScheduleDao->id));
1637 $this->assertCronRuns(array(
92c99a4a
EM
1638 array(
1639 // On some random day, no email.
43030baf
AH
1640 'time' => '2014-03-07 01:00:00',
1641 'recipients' => array(),
1642 ),
92c99a4a
EM
1643 array(
1644 // On the eve of their 9th birthday, send an email.
43030baf
AH
1645 'time' => '2014-07-06 20:00:00',
1646 'recipients' => array(array('test-bday@example.com')),
1647 ),
1648 ));
1649 }
4b1efa1d 1650
92c99a4a 1651 public function testContactCustomDateNoAnniv() {
43030baf
AH
1652 $group = array(
1653 'title' => 'Test_Group',
1654 'name' => 'test_group',
1655 'extends' => array('Individual'),
1656 'style' => 'Inline',
6c6e6187 1657 'is_multiple' => FALSE,
43030baf 1658 'is_active' => 1,
43030baf 1659 );
bf308d29 1660 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 1661 $field = array(
43030baf
AH
1662 'label' => 'Graduation',
1663 'data_type' => 'Date',
1664 'html_type' => 'Select Date',
1665 'custom_group_id' => $createGroup['id'],
1666 );
bf308d29 1667 $createField = $this->callAPISuccess('custom_field', 'create', $field);
43030baf
AH
1668 $contactParams = $this->fixtures['contact'];
1669 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 1670 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
1671 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1672 $actionSchedule = $this->fixtures['sched_contact_grad_tomorrow'];
1673 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1674 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1675 $this->assertTrue(is_numeric($actionScheduleDao->id));
1676 $this->assertCronRuns(array(
92c99a4a
EM
1677 array(
1678 // On some random day, no email.
43030baf
AH
1679 'time' => '2014-03-07 01:00:00',
1680 'recipients' => array(),
1681 ),
92c99a4a
EM
1682 array(
1683 // On the eve of their graduation, send an email.
43030baf
AH
1684 'time' => '2013-12-15 20:00:00',
1685 'recipients' => array(array('test-member@example.com')),
1686 ),
1687 ));
6c6e6187 1688 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
43030baf 1689 }
92915c55 1690
4aff0253
AH
1691 public function testContactCreatedNoAnniv() {
1692 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1693 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1694 $actionSchedule = $this->fixtures['sched_contact_created_yesterday'];
1695 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1696 $this->assertTrue(is_numeric($actionScheduleDao->id));
1697 $this->assertCronRuns(array(
1698 array(
1699 // On the date created, no email.
1700 'time' => $contact['values'][$contact['id']]['created_date'],
1701 'recipients' => array(),
1702 ),
1703 array(
1704 // The next day, send an email.
1705 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['created_date'] . ' +1 day')),
1706 'recipients' => array(array('test-bday@example.com')),
1707 ),
1708 ));
1709 }
1710
1711 public function testContactModifiedAnniversary() {
1712 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1713 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
688bd604 1714 $modifiedDate = $this->callAPISuccess('Contact', 'getvalue', array('id' => $contact['id'], 'return' => 'modified_date'));
4aff0253
AH
1715 $actionSchedule = $this->fixtures['sched_contact_mod_anniv'];
1716 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1717 $this->assertTrue(is_numeric($actionScheduleDao->id));
1718 $this->assertCronRuns(array(
1719 array(
1720 // On some random day, no email.
a9ac9f6c 1721 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' -60 days')),
4aff0253
AH
1722 'recipients' => array(),
1723 ),
1724 array(
1725 // On the eve of 3 years after they were modified, send an email.
688bd604 1726 'time' => date('Y-m-d H:i:s', strtotime($modifiedDate . ' +3 years -1 day')),
4aff0253
AH
1727 'recipients' => array(array('test-bday@example.com')),
1728 ),
1729 ));
1730 }
1731
baa85770 1732 /**
92c99a4a 1733 * Check that limit_to + an empty recipients doesn't sent to multiple contacts.
baa85770 1734 */
00be9182 1735 public function testMembershipLimitToNone() {
baa85770
EM
1736 // creates membership with end_date = 20120615
1737 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1738
1739 $this->assertTrue(is_numeric($membership->id));
1740 $result = $this->callAPISuccess('Email', 'create', array(
1741 'contact_id' => $membership->contact_id,
1742 'email' => 'member@example.com',
1743 ));
1744 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1745 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
1746
1747 $this->assertAPISuccess($result);
1748
1749 $actionSchedule = $this->fixtures['sched_membership_end_limit_to_none'];
1750 $actionSchedule['entity_value'] = $membership->membership_type_id;
1751 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1752 $this->assertTrue(is_numeric($actionScheduleDao->id));
1753
1754 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1755 $this->assertCronRuns(array(
92c99a4a
EM
1756 array(
1757 // Before the 2-week mark, no email.
baa85770
EM
1758 'time' => '2012-05-31 01:00:00',
1759 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
1760 'recipients' => array(),
1761 ),
1762 ));
1763 }
1764
cbcb7579 1765 public function testMembership_referenceDate() {
5c4d6559 1766 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1767
1768 $this->assertTrue(is_numeric($membership->id));
1769 $result = $this->callAPISuccess('Email', 'create', array(
1770 'contact_id' => $membership->contact_id,
1771 'email' => 'member@example.com',
1772 ));
1773
1774 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1775 $this->assertAPISuccess($result);
1776
1777 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1778 $actionSchedule['entity_value'] = $membership->membership_type_id;
1779 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1780 $this->assertTrue(is_numeric($actionScheduleDao->id));
1781
1782 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1783 $this->assertCronRuns(array(
cbcb7579
TO
1784 array(
1785 // After the 2-week mark, send an email
5c4d6559 1786 'time' => '2012-03-29 01:00:00',
1787 'recipients' => array(array('member@example.com')),
9c0fe051 1788 ),
cbcb7579
TO
1789 array(
1790 // After the 2-week 1day mark, don't send an email
9c0fe051 1791 'time' => '2012-03-30 01:00:00',
1792 'recipients' => array(),
1793 ),
5c4d6559 1794 ));
1795
1796 //check if reference date is set to membership's join date
1797 //as per the action_start_date chosen for current schedule reminder
e08fae02 1798 $this->assertEquals('2012-03-15 00:00:00',
5c4d6559 1799 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $membership->contact_id, 'reference_date', 'contact_id')
1800 );
1801
e7c6a902 1802 //change current membership join date that may signifies as membership renewal activity
5c4d6559 1803 $membership->join_date = '2012-03-29';
1804 $membership->save();
1805
5c4d6559 1806 $this->assertCronRuns(array(
cbcb7579
TO
1807 array(
1808 // After the 13 days of the changed join date 2012-03-29, don't send an email
9c0fe051 1809 'time' => '2012-04-11 01:00:00',
cbcb7579
TO
1810 'recipients' => array(),
1811 ),
1812 array(
1813 // After the 2-week of the changed join date 2012-03-29, send an email
5c4d6559 1814 'time' => '2012-04-12 01:00:00',
cbcb7579 1815 'recipients' => array(array('member@example.com')),
5c4d6559 1816 ),
1817 ));
7d48c97b 1818 $this->assertCronRuns(array(
1819 array(
1820 // It should not re-send on the same day
1821 'time' => '2012-04-12 01:00:00',
f8da3b93 1822 'recipients' => array(),
7d48c97b 1823 ),
1824 ));
5c4d6559 1825 }
baa85770 1826
d2868251 1827 public function testMembershipOnMultipleReminder() {
1828 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
d2868251 1829
1830 $this->assertTrue(is_numeric($membership->id));
1831 $result = $this->callAPISuccess('Email', 'create', array(
1832 'contact_id' => $membership->contact_id,
1833 'email' => 'member@example.com',
1834 ));
cbcb7579 1835 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
d2868251 1836 $this->assertAPISuccess($result);
1837
39b959db
SL
1838 // Send email 2 weeks before end_date
1839 $actionScheduleBefore = $this->fixtures['sched_membership_end_2week'];
1840 // Send email on end_date/expiry date
1841 $actionScheduleOn = $this->fixtures['sched_on_membership_end_date'];
1842 // Send email 1 day after end_date/grace period
1843 $actionScheduleAfter = $this->fixtures['sched_after_1day_membership_end_date'];
d2868251 1844 $actionScheduleBefore['entity_value'] = $actionScheduleOn['entity_value'] = $actionScheduleAfter['entity_value'] = $membership->membership_type_id;
1845 foreach (array('actionScheduleBefore', 'actionScheduleOn', 'actionScheduleAfter') as $value) {
1846 $$value = CRM_Core_BAO_ActionSchedule::add($$value);
1847 $this->assertTrue(is_numeric($$value->id));
1848 }
1849
1850 $this->assertCronRuns(
1851 array(
cbcb7579
TO
1852 array(
1853 // 1day 2weeks before membership end date(MED), don't send mail
d2868251 1854 'time' => '2012-05-31 01:00:00',
1855 'recipients' => array(),
1856 ),
cbcb7579
TO
1857 array(
1858 // 2 weeks before MED, send an email
d2868251 1859 'time' => '2012-06-01 01:00:00',
1860 'recipients' => array(array('member@example.com')),
1861 ),
cbcb7579
TO
1862 array(
1863 // 1day before MED, don't send mail
d2868251 1864 'time' => '2012-06-14 01:00:00',
1865 'recipients' => array(),
1866 ),
cbcb7579
TO
1867 array(
1868 // On MED, send an email
d2868251 1869 'time' => '2012-06-15 00:00:00',
1870 'recipients' => array(array('member@example.com')),
1871 ),
cbcb7579
TO
1872 array(
1873 // After 1day of MED, send an email
d2868251 1874 'time' => '2012-06-16 01:00:00',
1875 'recipients' => array(array('member@example.com')),
1876 ),
cbcb7579
TO
1877 array(
1878 // After 1day 1min of MED, don't send an email
d2868251 1879 'time' => '2012-06-17 00:01:00',
1880 'recipients' => array(),
1881 ),
cbcb7579
TO
1882 )
1883 );
d2868251 1884
1885 // Assert the timestamp as of when the emails of respective three reminders as configured
1886 // 2 weeks before, on and 1 day after MED, are sent
f42ab010
TO
1887 $this->assertApproxEquals(
1888 strtotime('2012-06-01 01:00:00'),
1889 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleBefore->id, 'action_date_time', 'action_schedule_id', TRUE)),
39b959db
SL
1890 // Variation in test execution time.
1891 3
f42ab010
TO
1892 );
1893 $this->assertApproxEquals(
1894 strtotime('2012-06-15 00:00:00'),
1895 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleOn->id, 'action_date_time', 'action_schedule_id', TRUE)),
39b959db
SL
1896 // Variation in test execution time.
1897 3
f42ab010
TO
1898 );
1899 $this->assertApproxEquals(
1900 strtotime('2012-06-16 01:00:00'),
1901 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleAfter->id, 'action_date_time', 'action_schedule_id', TRUE)),
39b959db
SL
1902 // Variation in test execution time.
1903 3
f42ab010 1904 );
d2868251 1905
e7c6a902 1906 //extend MED to 2 weeks after the current MED (that may signifies as membership renewal activity)
d2868251 1907 // and lets assert as of when the new set of reminders will be sent against their respective Schedule Reminders(SR)
9c0fe051 1908 $membership->end_date = '2012-06-20';
d2868251 1909 $membership->save();
d2868251 1910
9c0fe051 1911 $result = $this->callAPISuccess('Contact', 'get', array('id' => $membership->contact_id));
d2868251 1912 $this->assertCronRuns(
1913 array(
cbcb7579
TO
1914 array(
1915 // 1day 2weeks before membership end date(MED), don't send mail
9c0fe051 1916 'time' => '2012-06-05 01:00:00',
d2868251 1917 'recipients' => array(),
1918 ),
cbcb7579
TO
1919 array(
1920 // 2 weeks before MED, send an email
9c0fe051 1921 'time' => '2012-06-06 01:00:00',
1922 'recipients' => array(array('member@example.com')),
d2868251 1923 ),
cbcb7579
TO
1924 array(
1925 // 1day before MED, don't send mail
9c0fe051 1926 'time' => '2012-06-19 01:00:00',
d2868251 1927 'recipients' => array(),
1928 ),
cbcb7579
TO
1929 array(
1930 // On MED, send an email
9c0fe051 1931 'time' => '2012-06-20 00:00:00',
d2868251 1932 'recipients' => array(array('member@example.com')),
1933 ),
cbcb7579
TO
1934 array(
1935 // After 1day of MED, send an email
9c0fe051 1936 'time' => '2012-06-21 01:00:00',
d2868251 1937 'recipients' => array(array('member@example.com')),
1938 ),
cbcb7579
TO
1939 array(
1940 // After 1day 1min of MED, don't send an email
9c0fe051 1941 'time' => '2012-07-21 00:01:00',
d2868251 1942 'recipients' => array(),
1943 ),
d2868251 1944 ));
1945 }
1946
1947 public function testContactCustomDate_Anniv() {
43030baf
AH
1948 $group = array(
1949 'title' => 'Test_Group now',
1950 'name' => 'test_group_now',
1951 'extends' => array('Individual'),
1952 'style' => 'Inline',
6c6e6187 1953 'is_multiple' => FALSE,
43030baf 1954 'is_active' => 1,
43030baf 1955 );
bf308d29 1956 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 1957 $field = array(
43030baf
AH
1958 'label' => 'Graduation',
1959 'data_type' => 'Date',
1960 'html_type' => 'Select Date',
1961 'custom_group_id' => $createGroup['id'],
1962 );
bf308d29
EM
1963 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1964
43030baf
AH
1965 $contactParams = $this->fixtures['contact'];
1966 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 1967 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
1968 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1969 $actionSchedule = $this->fixtures['sched_contact_grad_anniv'];
1970 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1971 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1972 $this->assertTrue(is_numeric($actionScheduleDao->id));
1973 $this->assertCronRuns(array(
92c99a4a
EM
1974 array(
1975 // On some random day, no email.
43030baf
AH
1976 'time' => '2014-03-07 01:00:00',
1977 'recipients' => array(),
1978 ),
92c99a4a
EM
1979 array(
1980 // A week after their 5th anniversary of graduation, send an email.
43030baf
AH
1981 'time' => '2018-12-23 20:00:00',
1982 'recipients' => array(array('test-member@example.com')),
1983 ),
1984 ));
6c6e6187 1985 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
43030baf 1986 }
4b1efa1d 1987
76ea51c7
JP
1988 /**
1989 * Test sched reminder set via registration date.
1990 */
1991 public function testEventTypeRegistrationDate() {
1992 //Create contact
1993 $contactParams = array(
1994 'email' => 'test-event@example.com',
1995 );
1996 $contact = $this->individualCreate($contactParams);
1997 //Add it as a participant to an event ending registration - 7 days from now.
1998 $params = array(
1999 'start_date' => date('Ymd', strtotime('-5 day')),
2000 'end_date' => date('Ymd', strtotime('+7 day')),
2001 'registration_start_date' => date('Ymd', strtotime('-5 day')),
2002 'registration_end_date' => date('Ymd', strtotime('+7 day')),
2003 );
2004 $event = $this->eventCreate($params);
2005 $this->participantCreate(array('contact_id' => $contact, 'event_id' => $event['id']));
2006
2007 //Create a scheduled reminder to send email 7 days before registration date.
2008 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
2009 $actionSchedule['start_action_offset'] = 7;
2010 $actionSchedule['start_action_unit'] = 'day';
2011 $actionSchedule['start_action_date'] = 'registration_end_date';
2012 $actionSchedule['entity_value'] = $event['values'][$event['id']]['event_type_id'];
2013 $actionSchedule['entity_status'] = $this->callAPISuccessGetValue('ParticipantStatusType', array(
2014 'return' => "id",
2015 'name' => "Attended",
2016 ));
899bd155 2017 $actionSched = $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
76ea51c7
JP
2018 //Run the cron and verify if an email was sent.
2019 $this->assertCronRuns(array(
2020 array(
2021 'time' => date('Y-m-d'),
2022 'recipients' => array(array('test-event@example.com')),
2023 ),
2024 ));
899bd155
JP
2025
2026 //Create contact 2
2027 $contactParams = array(
2028 'email' => 'test-event2@example.com',
2029 );
2030 $contact2 = $this->individualCreate($contactParams);
2031 //Create an event with registration end date = 2 week from now.
2032 $params['end_date'] = date('Ymd', strtotime('+2 week'));
2033 $params['registration_end_date'] = date('Ymd', strtotime('+2 week'));
2034 $event2 = $this->eventCreate($params);
2035 $this->participantCreate(array('contact_id' => $contact2, 'event_id' => $event2['id']));
2036
2037 //Assert there is no reminder sent to the contact.
2038 $this->assertCronRuns(array(
2039 array(
2040 'time' => date('Y-m-d'),
2041 'recipients' => array(),
2042 ),
2043 ));
2044
2045 //Modify the sched reminder to be sent 2 week from registration end date.
2046 $this->callAPISuccess('action_schedule', 'create', array(
2047 'id' => $actionSched['id'],
2048 'start_action_offset' => 2,
2049 'start_action_unit' => 'week',
2050 ));
2051
2052 //Contact should receive the reminder now.
2053 $this->assertCronRuns(array(
2054 array(
2055 'time' => date('Y-m-d'),
2056 'recipients' => array(array('test-event2@example.com')),
2057 ),
2058 ));
76ea51c7
JP
2059 }
2060
2061 /**
2062 * Test sched reminder set via start date.
2063 */
d3eae6ea
TO
2064 public function testEventTypeStartDate() {
2065 // Create event+participant with start_date = 20120315, end_date = 20120615.
2066 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
2067 $this->callAPISuccess('Email', 'create', array(
2068 'contact_id' => $participant->contact_id,
2069 'email' => 'test-event@example.com',
2070 ));
2071 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
2072
2073 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
2074 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
2075 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
2076
2077 //echo "CREATED\n"; ob_flush(); sleep(20);
2078
2079 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
2080 $this->assertCronRuns(array(
2081 array(
2082 // 2 weeks before
2083 'time' => '2012-03-02 01:00:00',
2084 'recipients' => array(),
2085 ),
2086 array(
2087 // 1 week before
2088 'time' => '2012-03-08 01:00:00',
2089 'recipients' => array(array('test-event@example.com')),
2090 ),
2091 array(
2092 // And then nothing else
2093 'time' => '2012-03-16 01:00:00',
2094 'recipients' => array(),
2095 ),
2096 ));
2097 }
2098
2099 public function testEventTypeEndDateRepeat() {
2100 // Create event+participant with start_date = 20120315, end_date = 20120615.
2101 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
2102 $this->callAPISuccess('Email', 'create', array(
2103 'contact_id' => $participant->contact_id,
2104 'email' => 'test-event@example.com',
2105 ));
2106 $c = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
2107
2108 $actionSchedule = $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'];
2109 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
2110 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
2111
2112 $this->assertCronRuns(array(
2113 array(
2114 // Almost 2 months.
2115 'time' => '2012-08-13 01:00:00',
2116 'recipients' => array(),
2117 ),
2118 array(
2119 // After the 2-month mark, send an email.
2120 'time' => '2012-08-16 01:00:00',
2121 'recipients' => array(array('test-event@example.com')),
2122 ),
2123 array(
2124 // After 2 months and 1 week, don't repeat yet.
2125 'time' => '2012-08-23 02:00:00',
2126 'recipients' => array(),
2127 ),
2128 array(
2129 // After 2 months and 2 weeks
2130 'time' => '2012-08-30 02:00:00',
2131 'recipients' => array(array('test-event@example.com')),
2132 ),
2133 array(
2134 // After 2 months and 4 week
2135 'time' => '2012-09-13 02:00:00',
2136 'recipients' => array(array('test-event@example.com')),
2137 ),
2138 array(
2139 // After 2 months and 6 weeks
2140 'time' => '2012-09-27 01:00:00',
2141 'recipients' => array(),
2142 ),
2143 ));
2144 }
2145
6a488035
TO
2146 // TODO // function testMembershipEndDate_NonMatch() { }
2147 // TODO // function testEventTypeStartDate_Match() { }
2148 // TODO // function testEventTypeEndDate_Match() { }
2149 // TODO // function testEventNameStartDate_Match() { }
2150 // TODO // function testEventNameEndDate_Match() { }
2151
2152 /**
92c99a4a 2153 * Run a series of cron jobs and make an assertion about email deliveries.
6a488035 2154 *
16b10e64
CW
2155 * @param array $cronRuns
2156 * array specifying when to run cron and what messages to expect; each item is an array with keys:
2157 * - time: string, e.g. '2012-06-15 21:00:01'
2158 * - recipients: array(array(string)), list of email addresses which should receive messages
6a488035 2159 */
00be9182 2160 public function assertCronRuns($cronRuns) {
6a488035
TO
2161 foreach ($cronRuns as $cronRun) {
2162 CRM_Utils_Time::setTime($cronRun['time']);
bf308d29 2163 $this->callAPISuccess('job', 'send_reminder', array());
6a488035 2164 $this->mut->assertRecipients($cronRun['recipients']);
f8c3594b
TO
2165 if (array_key_exists('subjects', $cronRun)) {
2166 $this->mut->assertSubjects($cronRun['subjects']);
2167 }
6a488035
TO
2168 $this->mut->clearMessages();
2169 }
2170 }
2171
6a488035
TO
2172 /**
2173 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
2174 */
2175 private $_testObjects;
2176
2177 /**
2178 * Sets up the fixture, for example, opens a network connection.
92c99a4a 2179 *
6a488035 2180 * This method is called before a test is executed.
6a488035
TO
2181 */
2182 protected function _setUp() {
2183 $this->_testObjects = array();
2184 }
2185
2186 /**
2187 * Tears down the fixture, for example, closes a network connection.
92c99a4a 2188 *
6a488035 2189 * This method is called after a test is executed.
6a488035
TO
2190 */
2191 protected function _tearDown() {
2192 parent::tearDown();
2193 $this->deleteTestObjects();
2194 }
2195
2196 /**
2197 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
92c99a4a 2198 * created entities and provides for brainless cleanup.
6a488035
TO
2199 *
2200 * @see CRM_Core_DAO::createTestObject
92c99a4a 2201 *
1e1fdcf6
EM
2202 * @param $daoName
2203 * @param array $params
2204 * @param int $numObjects
2205 * @param bool $createOnly
92c99a4a
EM
2206 *
2207 * @return array|NULL|object
6a488035 2208 */
2da40d21 2209 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
6a488035
TO
2210 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
2211 if (is_array($objects)) {
2212 $this->registerTestObjects($objects);
0db6c3e1
TO
2213 }
2214 else {
6a488035
TO
2215 $this->registerTestObjects(array($objects));
2216 }
2217 return $objects;
2218 }
2219
2220 /**
5a4f6742
CW
2221 * @param array $objects
2222 * DAO or BAO objects.
6a488035 2223 */
00be9182 2224 public function registerTestObjects($objects) {
6a488035
TO
2225 //if (is_object($objects)) {
2226 // $objects = array($objects);
2227 //}
2228 foreach ($objects as $object) {
2229 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
2230 $this->_testObjects[$daoName][] = $object->id;
2231 }
2232 }
2233
00be9182 2234 public function deleteTestObjects() {
6a488035
TO
2235 // Note: You might argue that the FK relations between test
2236 // objects could make this problematic; however, it should
2237 // behave intuitively as long as we mentally split our
2238 // test-objects between the "manual/primary records"
2239 // and the "automatic/secondary records"
2240 foreach ($this->_testObjects as $daoName => $daoIds) {
2241 foreach ($daoIds as $daoId) {
2242 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
2243 }
2244 }
2245 $this->_testObjects = array();
2246 }
2247
52f09320
PH
2248 /**
2249 * Test that the various repetition units work correctly.
2250 * CRM-17028
2251 */
2252 public function testRepetitionFrequencyUnit() {
2253 $membershipTypeParams = array(
2254 'duration_interval' => '1',
2255 'duration_unit' => 'year',
2256 'is_active' => 1,
2257 'period_type' => 'rolling',
2258 );
2259 $membershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipTypeParams);
2260 $interval_units = array('hour', 'day', 'week', 'month', 'year');
2261 foreach ($interval_units as $interval_unit) {
2262 $membershipEndDate = DateTime::createFromFormat('Y-m-d H:i:s', "2013-03-15 00:00:00");
2263 $contactParams = array(
2264 'contact_type' => 'Individual',
2265 'first_name' => 'Test',
2266 'last_name' => "Interval $interval_unit",
2267 'is_deceased' => 0,
2268 );
2269 $contact = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2270 $this->assertTrue(is_numeric($contact->id));
2271 $emailParams = array(
2272 'contact_id' => $contact->id,
62ca07e7 2273 'is_primary' => 1,
52f09320
PH
2274 'email' => "test-member-{$interval_unit}@example.com",
2275 'location_type_id' => 1,
2276 );
2277 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2278 $this->assertTrue(is_numeric($email->id));
2279 $membershipParams = array(
2280 'membership_type_id' => $membershipType->id,
2281 'contact_id' => $contact->id,
2282 'join_date' => '20120315',
2283 'start_date' => '20120315',
2284 'end_date' => '20130315',
2285 'is_override' => 0,
2286 'status_id' => 2,
2287 );
2288 $membershipParams['status-id'] = 1;
2289 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2290 $actionScheduleParams = $this->fixtures['sched_on_membership_end_date_repeat_interval'];
2291 $actionScheduleParams['entity_value'] = $membershipType->id;
2292 $actionScheduleParams['repetition_frequency_unit'] = $interval_unit;
2293 $actionScheduleParams['repetition_frequency_interval'] = 2;
2294 $actionSchedule = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
2295 $this->assertTrue(is_numeric($actionSchedule->id));
2296 $beforeEndDate = $this->createModifiedDateTime($membershipEndDate, '-1 day');
2297 $beforeFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+1 $interval_unit");
2298 $afterFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+2 $interval_unit");
2299 $cronRuns = array(
2300 array(
2301 'time' => $beforeEndDate->format('Y-m-d H:i:s'),
2302 'recipients' => array(),
2303 ),
2304 array(
2305 'time' => $membershipEndDate->format('Y-m-d H:i:s'),
2306 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2307 ),
2308 array(
2309 'time' => $beforeFirstUnit->format('Y-m-d H:i:s'),
2310 'recipients' => array(),
2311 ),
2312 array(
2313 'time' => $afterFirstUnit->format('Y-m-d H:i:s'),
2314 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2315 ),
2316 );
2317 $this->assertCronRuns($cronRuns);
2318 $actionSchedule->delete();
2319 $membership->delete();
2320 }
2321 }
2322
bb3ba83e
AH
2323 /**
2324 * Inherited members without permission to edit the main member contact should
2325 * not get reminders.
2326 *
2327 * However, just because a contact inherits one membership doesn't mean
2328 * reminders for other memberships should be suppressed.
2329 *
2330 * See CRM-14098
2331 */
2332 public function testInheritedMembershipPermissions() {
2333 // Set up common parameters for memberships.
2334 $membershipParams = $this->fixtures['rolling_membership'];
2335 $membershipParams['status_id'] = 1;
2336
2337 $membershipParams['membership_type_id']['relationship_type_id'] = 1;
2338 $membershipParams['membership_type_id']['relationship_direction'] = 'b_a';
2339 $membershipType1 = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipParams['membership_type_id']);
2340
2341 // We'll create a new membership type that can be held at the same time as
2342 // the first one.
2343 $membershipParams['membership_type_id']['relationship_type_id'] = 'NULL';
2344 $membershipParams['membership_type_id']['relationship_direction'] = 'NULL';
2345 $membershipType2 = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipParams['membership_type_id']);
2346
2347 // Create the parent membership and contact
2348 $membershipParams['membership_type_id'] = $membershipType1->id;
2349 $mainMembership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2350
2351 $contactParams = [
2352 'contact_type' => 'Individual',
2353 'first_name' => 'Mom',
2354 'last_name' => 'Rel',
2355 'is_deceased' => 0,
2356 ];
2357 $this->createTestObject('CRM_Contact_DAO_Contact', array_merge($contactParams, ['id' => $mainMembership->contact_id]));
2358
2359 $emailParams = [
2360 'contact_id' => $mainMembership->contact_id,
2361 'email' => 'test-member@example.com',
2362 'location_type_id' => 1,
2363 'is_primary' => 1,
2364 ];
2365 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2366
2367 // Set up contacts and emails for the two children
2368 $contactParams['first_name'] = 'Favorite';
2369 $permChild = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2370 $emailParams['email'] = 'favorite@example.com';
2371 $emailParams['contact_id'] = $permChild->id;
2372 $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2373
2374 $contactParams['first_name'] = 'Black Sheep';
2375 $nonPermChild = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2376 $emailParams['email'] = 'black.sheep@example.com';
2377 $emailParams['contact_id'] = $nonPermChild->id;
2378 $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2379
2380 // Each child gets a relationship, one with permission to edit the parent. This
2381 // will trigger inherited memberships for the first membership type
2382 $relParams = [
2383 'relationship_type_id' => 1,
2384 'contact_id_a' => $nonPermChild->id,
2385 'contact_id_b' => $mainMembership->contact_id,
2386 'is_active' => 1,
2387 ];
2388 $this->callAPISuccess('relationship', 'create', $relParams);
2389
2390 $relParams['contact_id_a'] = $permChild->id;
2391 $relParams['is_permission_a_b'] = CRM_Contact_BAO_Relationship::EDIT;
2392 $this->callAPISuccess('relationship', 'create', $relParams);
2393
2394 // Mom and Black Sheep get their own memberships of the second type.
2395 $membershipParams['membership_type_id'] = $membershipType2->id;
2396 $membershipParams['owner_membership_id'] = 'NULL';
2397 $membershipParams['contact_id'] = $mainMembership->contact_id;
2398 $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2399
2400 $membershipParams['contact_id'] = $nonPermChild->id;
2401 $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2402
2403 // Test a reminder for the first membership type - that should exclude Black
2404 // Sheep.
2405 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
2406 $actionSchedule['entity_value'] = $membershipType1->id;
2407 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
2408 $this->assertTrue(is_numeric($actionScheduleDao->id));
2409
2410 $this->assertCronRuns([
2411 [
2412 'time' => '2012-03-29 01:00:00',
2413 'recipients' => [['test-member@example.com'], ['favorite@example.com']],
2414 'subjects' => [
2415 'subject sched_membership_join_2week (joined March 15th, 2012)',
2416 'subject sched_membership_join_2week (joined March 15th, 2012)',
2417 ],
2418 ],
2419 ]);
2420
2421 // Test a reminder for the second membership type - that should include
2422 // Black Sheep.
2423 $actionSchedule = $this->fixtures['sched_membership_start_1week'];
2424 $actionSchedule['entity_value'] = $membershipType2->id;
2425 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
2426 $this->assertTrue(is_numeric($actionScheduleDao->id));
2427
2428 $this->assertCronRuns([
2429 [
2430 'time' => '2012-03-22 01:00:00',
2431 'recipients' => [['test-member@example.com'], ['black.sheep@example.com']],
2432 'subjects' => [
2433 'subject sched_membership_start_1week (joined March 15th, 2012)',
2434 'subject sched_membership_start_1week (joined March 15th, 2012)',
2435 ],
2436 ],
2437 ]);
2438 }
2439
52f09320
PH
2440 public function createModifiedDateTime($origDateTime, $modifyRule) {
2441 $newDateTime = clone($origDateTime);
2442 $newDateTime->modify($modifyRule);
2443 return $newDateTime;
2444 }
2445
e08fae02
PH
2446 public function testMembershipScheduleWithAbsoluteDate() {
2447 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
2448 $this->assertTrue(is_numeric($membership->id));
2449 $result = $this->callAPISuccess('Email', 'create', array(
2450 'contact_id' => $membership->contact_id,
2451 'email' => 'test-member@example.com',
2452 'location_type_id' => 1,
2453 'is_primary' => 1,
2454 ));
2455
2456 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
2457 $actionSchedule = $this->fixtures['sched_membership_absolute_date'];
2458 $actionSchedule['entity_value'] = $membership->membership_type_id;
2459 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
2460 $this->assertTrue(is_numeric($actionScheduleDao->id));
2461
2462 $this->assertCronRuns(array(
2463 array(
2464 // Before the 24-hour mark, no email
2465 'time' => '2012-06-13 04:00:00',
2466 'recipients' => array(),
2467 'subjects' => array(),
2468 ),
2469 array(
2470 // On absolute date set on 2012-06-14
2471 'time' => '2012-06-14 00:00:00',
2472 'recipients' => array(array('test-member@example.com')),
2473 'subjects' => array('subject sched_membership_absolute_date'),
2474 ),
2475 array(
2476 // Run cron 4 hours later; first message already sent
2477 'time' => '2012-06-14 04:00:00',
2478 'recipients' => array(),
2479 'subjects' => array(),
2480 ),
2481 ));
2482 }
2483
6a488035 2484}