phpcs - Fix error, "CONST keyword must be lowercase; expected const but found CONST"
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / ActionScheduleTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
06a1bc01 6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 +--------------------------------------------------------------------+
26*/
27
28
29require_once 'CiviTest/CiviUnitTestCase.php';
e9479dcf
EM
30
31/**
32 * Class CRM_Core_BAO_ActionScheduleTest
33 */
6a488035
TO
34class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
35 /**
36 * @var object see CiviTest/CiviMailUtils
37 */
38 var $mut;
cee19268 39
6a488035
TO
40 function setUp() {
41 parent::setUp();
42
43 require_once 'CiviTest/CiviMailUtils.php';
44 $this->mut = new CiviMailUtils($this, true);
45
46 $this->fixtures['rolling_membership'] = array( // createTestObject
47 'membership_type_id' => array(
48 'period_type' => 'rolling',
49 'duration_unit' => 'month',
50 'duration_interval' => '3',
51 'is_active' => 1,
52 ),
53 'join_date' => '20120315',
54 'start_date' => '20120315',
55 'end_date' => '20120615',
b29be8c2 56 'is_override' => 0,
6a488035 57 );
4b1efa1d 58
59 $this->fixtures['rolling_membership_past'] = array( // createTestObject
60 'membership_type_id' => array(
61 'period_type' => 'rolling',
62 'duration_unit' => 'month',
63 'duration_interval' => '3',
64 'is_active' => 1,
65 ),
66 'join_date' => '20100310',
67 'start_date' => '20100310',
68 'end_date' => '20100610',
69 'is_override' => 'NULL',
70 );
fe265b4e 71
6a488035
TO
72 $this->fixtures['phonecall'] = array( // createTestObject
73 'status_id' => 1,
74 'activity_type_id' => 2,
75 'activity_date_time' => '20120615100000',
76 'is_current_revision' => 1,
77 'is_deleted' => 0,
78 );
79 $this->fixtures['contact'] = array( // API
b29be8c2 80 'is_deceased' => 0,
6a488035
TO
81 'contact_type' => 'Individual',
82 'email' => 'test-member@example.com',
83 );
43030baf 84 $this->fixtures['contact_birthdate'] = array( // API
43030baf
AH
85 'is_deceased' => 0,
86 'contact_type' => 'Individual',
87 'email' => 'test-bday@example.com',
88 'birth_date' => '20050707',
89 );
6a488035
TO
90 $this->fixtures['sched_activity_1day'] = array( // create()
91 'name' => 'One_Day_Phone_Call_Notice',
92 'title' => 'One Day Phone Call Notice',
84a3e359 93 'limit_to' => '1',
6a488035
TO
94 'absolute_date' => NULL,
95 'body_html' => '<p>1-Day (non-repeating)</p>',
96 'body_text' => '1-Day (non-repeating)',
97 'end_action' => NULL,
98 'end_date' => NULL,
99 'end_frequency_interval' => NULL,
100 'end_frequency_unit' => NULL,
101 'entity_status' => '1',
102 'entity_value' => '2',
103 'group_id' => NULL,
104 'is_active' => '1',
105 'is_repeat' => '0',
106 'mapping_id' => '1',
107 'msg_template_id' => NULL,
108 'recipient' => '2',
109 'recipient_listing' => NULL,
110 'recipient_manual' => NULL,
111 'record_activity' => NULL,
112 'repetition_frequency_interval' => NULL,
113 'repetition_frequency_unit' => NULL,
114 'start_action_condition' => 'before',
115 'start_action_date' => 'activity_date_time',
116 'start_action_offset' => '1',
117 'start_action_unit' => 'day',
118 'subject' => '1-Day (non-repeating)',
119 );
120 $this->fixtures['sched_activity_1day_r'] = array(
121 'name' => 'One_Day_Phone_Call_Notice_R',
122 'title' => 'One Day Phone Call Notice R',
84a3e359 123 'limit_to' => 1,
6a488035
TO
124 'absolute_date' => NULL,
125 'body_html' => '<p>1-Day (repeating)</p>',
126 'body_text' => '1-Day (repeating)',
127 'end_action' => 'after',
128 'end_date' => 'activity_date_time',
129 'end_frequency_interval' => '2',
130 'end_frequency_unit' => 'day',
131 'entity_status' => '1',
132 'entity_value' => '2',
133 'group_id' => NULL,
134 'is_active' => '1',
135 'is_repeat' => '1',
136 'mapping_id' => '1',
137 'msg_template_id' => NULL,
138 'recipient' => '2',
139 'recipient_listing' => NULL,
140 'recipient_manual' => NULL,
141 'record_activity' => NULL,
142 'repetition_frequency_interval' => '6',
143 'repetition_frequency_unit' => 'hour',
144 'start_action_condition' => 'before',
145 'start_action_date' => 'activity_date_time',
146 'start_action_offset' => '1',
147 'start_action_unit' => 'day',
148 'subject' => '1-Day (repeating)',
149 );
150 $this->fixtures['sched_membership_join_2week'] = array( // create()
151 'name' => 'sched_membership_join_2week',
152 'title' => 'sched_membership_join_2week',
153 'absolute_date' => '',
154 'body_html' => '<p>body sched_membership_join_2week</p>',
155 'body_text' => 'body sched_membership_join_2week',
156 'end_action' => '',
157 'end_date' => '',
158 'end_frequency_interval' => '',
159 'end_frequency_unit' => '',
160 'entity_status' => '',
161 'entity_value' => '',
162 'group_id' => '',
163 'is_active' => 1,
164 'is_repeat' => '0',
165 'mapping_id' => 4,
166 'msg_template_id' => '',
167 'recipient' => '',
168 'recipient_listing' => '',
169 'recipient_manual' => '',
170 'record_activity' => 1,
171 'repetition_frequency_interval' => '',
172 'repetition_frequency_unit' => '',
173 'start_action_condition' => 'after',
174 'start_action_date' => 'membership_join_date',
175 'start_action_offset' => '2',
176 'start_action_unit' => 'week',
177 'subject' => 'subject sched_membership_join_2week',
178 );
179 $this->fixtures['sched_membership_end_2week'] = array( // create()
180 'name' => 'sched_membership_end_2week',
181 'title' => 'sched_membership_end_2week',
182 'absolute_date' => '',
183 'body_html' => '<p>body sched_membership_end_2week</p>',
184 'body_text' => 'body sched_membership_end_2week',
185 'end_action' => '',
186 'end_date' => '',
187 'end_frequency_interval' => '',
188 'end_frequency_unit' => '',
189 'entity_status' => '',
190 'entity_value' => '',
191 'group_id' => '',
192 'is_active' => 1,
193 'is_repeat' => '0',
194 'mapping_id' => 4,
195 'msg_template_id' => '',
196 'recipient' => '',
197 'recipient_listing' => '',
198 'recipient_manual' => '',
199 'record_activity' => 1,
200 'repetition_frequency_interval' => '',
201 'repetition_frequency_unit' => '',
202 'start_action_condition' => 'before',
203 'start_action_date' => 'membership_end_date',
204 'start_action_offset' => '2',
205 'start_action_unit' => 'week',
206 'subject' => 'subject sched_membership_end_2week',
207 );
4b1efa1d 208
209 $this->fixtures['sched_membership_end_2month'] = array( // create()
210 'name' => 'sched_membership_end_2month',
211 'title' => 'sched_membership_end_2month',
212 'absolute_date' => '',
213 'body_html' => '<p>body sched_membership_end_2month</p>',
214 'body_text' => 'body sched_membership_end_2month',
215 'end_action' => '',
216 'end_date' => '',
217 'end_frequency_interval' => '',
218 'end_frequency_unit' => '',
219 'entity_status' => '',
220 'entity_value' => '',
221 'group_id' => '',
222 'is_active' => 1,
223 'is_repeat' => '0',
224 'mapping_id' => 4,
225 'msg_template_id' => '',
226 'recipient' => '',
227 'recipient_listing' => '',
228 'recipient_manual' => '',
229 'record_activity' => 1,
230 'repetition_frequency_interval' => '',
231 'repetition_frequency_unit' => '',
232 'start_action_condition' => 'after',
233 'start_action_date' => 'membership_end_date',
234 'start_action_offset' => '2',
235 'start_action_unit' => 'month',
236 'subject' => 'subject sched_membership_end_2month',
237 );
238
43030baf
AH
239 $this->fixtures['sched_contact_bday_yesterday'] = array( // create()
240 'name' => 'sched_contact_bday_yesterday',
241 'title' => 'sched_contact_bday_yesterday',
242 'absolute_date' => '',
243 'body_html' => '<p>you look like you were born yesterday!</p>',
244 'body_text' => 'you look like you were born yesterday!',
245 'end_action' => '',
246 'end_date' => '',
247 'end_frequency_interval' => '',
248 'end_frequency_unit' => '',
249 'entity_status' => 1,
250 'entity_value' => 'birth_date',
251 'group_id' => '',
252 'is_active' => 1,
253 'is_repeat' => '0',
254 'mapping_id' => 6,
255 'msg_template_id' => '',
256 'recipient' => '',
257 'recipient_listing' => '',
258 'recipient_manual' => '',
259 'record_activity' => 1,
260 'repetition_frequency_interval' => '',
261 'repetition_frequency_unit' => '',
262 'start_action_condition' => 'after',
263 'start_action_date' => 'date_field',
264 'start_action_offset' => '1',
265 'start_action_unit' => 'day',
266 'subject' => 'subject sched_contact_bday_yesterday',
267 );
268
269 $this->fixtures['sched_contact_bday_anniv'] = array( // create()
270 'name' => 'sched_contact_bday_anniv',
271 'title' => 'sched_contact_bday_anniv',
272 'absolute_date' => '',
273 'body_html' => '<p>happy birthday!</p>',
274 'body_text' => 'happy birthday!',
275 'end_action' => '',
276 'end_date' => '',
277 'end_frequency_interval' => '',
278 'end_frequency_unit' => '',
279 'entity_status' => 2,
280 'entity_value' => 'birth_date',
281 'group_id' => '',
282 'is_active' => 1,
283 'is_repeat' => '0',
284 'mapping_id' => 6,
285 'msg_template_id' => '',
286 'recipient' => '',
287 'recipient_listing' => '',
288 'recipient_manual' => '',
289 'record_activity' => 1,
290 'repetition_frequency_interval' => '',
291 'repetition_frequency_unit' => '',
292 'start_action_condition' => 'before',
293 'start_action_date' => 'date_field',
294 'start_action_offset' => '1',
295 'start_action_unit' => 'day',
296 'subject' => 'subject sched_contact_bday_anniv',
297 );
298
299 $this->fixtures['sched_contact_grad_tomorrow'] = array( // create()
300 'name' => 'sched_contact_grad_tomorrow',
301 'title' => 'sched_contact_grad_tomorrow',
302 'absolute_date' => '',
303 'body_html' => '<p>congratulations on your graduation!</p>',
304 'body_text' => 'congratulations on your graduation!',
305 'end_action' => '',
306 'end_date' => '',
307 'end_frequency_interval' => '',
308 'end_frequency_unit' => '',
309 'entity_status' => 1,
310 'group_id' => '',
311 'is_active' => 1,
312 'is_repeat' => '0',
313 'mapping_id' => 6,
314 'msg_template_id' => '',
315 'recipient' => '',
316 'recipient_listing' => '',
317 'recipient_manual' => '',
318 'record_activity' => 1,
319 'repetition_frequency_interval' => '',
320 'repetition_frequency_unit' => '',
321 'start_action_condition' => 'before',
322 'start_action_date' => 'date_field',
323 'start_action_offset' => '1',
324 'start_action_unit' => 'day',
325 'subject' => 'subject sched_contact_grad_tomorrow',
326 );
327
328 $this->fixtures['sched_contact_grad_anniv'] = array( // create()
329 'name' => 'sched_contact_grad_anniv',
330 'title' => 'sched_contact_grad_anniv',
331 'absolute_date' => '',
332 'body_html' => '<p>dear alum, please send us money.</p>',
333 'body_text' => 'dear alum, please send us money.',
334 'end_action' => '',
335 'end_date' => '',
336 'end_frequency_interval' => '',
337 'end_frequency_unit' => '',
338 'entity_status' => 2,
339 'group_id' => '',
340 'is_active' => 1,
341 'is_repeat' => '0',
342 'mapping_id' => 6,
343 'msg_template_id' => '',
344 'recipient' => '',
345 'recipient_listing' => '',
346 'recipient_manual' => '',
347 'record_activity' => 1,
348 'repetition_frequency_interval' => '',
349 'repetition_frequency_unit' => '',
350 'start_action_condition' => 'after',
351 'start_action_date' => 'date_field',
352 'start_action_offset' => '1',
353 'start_action_unit' => 'week',
354 'subject' => 'subject sched_contact_grad_anniv',
355 );
861d11c4
DG
356 $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'] = array( // create()
357 'name' => 'sched_membership_end_2month',
358 'title' => 'sched_membership_end_2month',
359 'absolute_date' => '',
360 'body_html' => '<p>body sched_membership_end_2month</p>',
361 'body_text' => 'body sched_membership_end_2month',
362 'end_action' => '',
363 'end_date' => '',
364 'end_frequency_interval' => '4',
365 'end_frequency_unit' => 'month',
366 'entity_status' => '',
367 'entity_value' => '',
368 'group_id' => '',
369 'is_active' => 1,
370 'is_repeat' => '1',
371 'mapping_id' => 4,
372 'msg_template_id' => '',
373 'recipient' => '',
374 'recipient_listing' => '',
375 'recipient_manual' => '',
376 'record_activity' => 1,
377 'repetition_frequency_interval' => '4',
378 'repetition_frequency_unit' => 'week',
379 'start_action_condition' => 'after',
380 'start_action_date' => 'membership_end_date',
381 'start_action_offset' => '2',
382 'start_action_unit' => 'month',
383 'subject' => 'subject sched_membership_end_2month',
384 );
baa85770
EM
385 $this->fixtures['sched_membership_end_limit_to_none'] = array( // create()
386 'name' => 'limit to none',
387 'title' => 'limit to none',
388 'absolute_date' => '',
389 'body_html' => '<p>body sched_membership_end_2month</p>',
390 'body_text' => 'body sched_membership_end_2month',
391 'end_action' => '',
392 'end_date' => '',
393 'end_frequency_interval' => '4',
394 'end_frequency_unit' => 'month',
395 'entity_status' => '',
396 'entity_value' => '',
397 'limit_to' => 0,
398 'group_id' => '',
399 'is_active' => 1,
400 'is_repeat' => '1',
401 'mapping_id' => 4,
402 'msg_template_id' => '',
403 'recipient' => '',
404 'recipient_listing' => '',
405 'recipient_manual' => '',
406 'record_activity' => 1,
407 'repetition_frequency_interval' => '4',
408 'repetition_frequency_unit' => 'week',
409 'start_action_condition' => 'after',
410 'start_action_date' => 'membership_end_date',
411 'start_action_offset' => '2',
412 'start_action_unit' => 'month',
413 'subject' => 'limit to none',
414 );
6a488035 415 $this->_setUp();
6a488035
TO
416 }
417
418 /**
419 * Tears down the fixture, for example, closes a network connection.
420 * This method is called after a test is executed.
421 *
422 * @access protected
423 */
424 function tearDown() {
425 parent::tearDown();
426
427 $this->mut->clearMessages();
428 $this->mut->stop();
429 unset($this->mut);
861d11c4 430 $this->quickCleanup(array('civicrm_action_schedule', 'civicrm_action_log', 'civicrm_membership', 'civicrm_email'));
6a488035
TO
431 $this->_tearDown();
432 }
433
434 function testActivityDateTime_Match_NonRepeatableSchedule() {
cee19268 435 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day']);
6a488035
TO
436 $this->assertTrue(is_numeric($actionScheduleDao->id));
437
438 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
6a488035 439 $this->assertTrue(is_numeric($activity->id));
bf308d29 440 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
6a488035
TO
441 $activity->save();
442
4f20f356 443 $source['contact_id'] = $contact['id'];
444 $source['activity_id'] = $activity->id;
445 $source['record_type_id'] = 2;
446 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
447 $activityContact->save();
448
6a488035
TO
449 $this->assertCronRuns(array(
450 array( // Before the 24-hour mark, no email
451 'time' => '2012-06-14 04:00:00',
452 'recipients' => array(),
453 ),
454 array( // After the 24-hour mark, an email
455 'time' => '2012-06-14 15:00:00',
456 'recipients' => array(array('test-member@example.com')),
457 ),
458 array( // Run cron again; message already sent
459 'time' => '',
460 'recipients' => array(),
461 ),
462 ));
463 }
464
465 function testActivityDateTime_Match_RepeatableSchedule() {
cee19268 466 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r']);
6a488035
TO
467 $this->assertTrue(is_numeric($actionScheduleDao->id));
468
469 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
470 $this->assertTrue(is_numeric($activity->id));
bf308d29 471 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
6a488035
TO
472 $activity->save();
473
4f20f356 474 $source['contact_id'] = $contact['id'];
475 $source['activity_id'] = $activity->id;
476 $source['record_type_id'] =2;
477 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
478 $activityContact->save();
479
6a488035
TO
480 $this->assertCronRuns(array(
481 array( // Before the 24-hour mark, no email
482 'time' => '012-06-14 04:00:00',
483 'recipients' => array(),
484 ),
485 array( // After the 24-hour mark, an email
486 'time' => '2012-06-14 15:00:00',
487 'recipients' => array(array('test-member@example.com')),
488 ),
489 array( // Run cron 4 hours later; first message already sent
490 'time' => '2012-06-14 20:00:00',
491 'recipients' => array(),
492 ),
493 array( // Run cron 6 hours later; send second message
494 'time' => '2012-06-14 21:00:01',
495 'recipients' => array(array('test-member@example.com')),
496 ),
497 ));
498 }
499
500 /**
501 * For contacts/activities which don't match the schedule filter,
502 * an email should *not* be sent.
503 */
504 // TODO // function testActivityDateTime_NonMatch() { }
505
506 /**
507 * For contacts/members which match schedule based on join date,
508 * an email should be sent.
509 */
510 function testMembershipJoinDate_Match() {
b29be8c2 511 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
6a488035 512 $this->assertTrue(is_numeric($membership->id));
bf308d29 513 $result = $this->callAPISuccess('Email', 'create', array(
6a488035
TO
514 'contact_id' => $membership->contact_id,
515 'email' => 'test-member@example.com',
516 'location_type_id' => 1,
bf308d29 517 ));
6a488035
TO
518 $this->assertAPISuccess($result);
519
bf308d29 520 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
6a488035
TO
521 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
522 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 523 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
6a488035
TO
524 $this->assertTrue(is_numeric($actionScheduleDao->id));
525
526 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
527 $this->assertCronRuns(array(
528 array( // Before the 2-week mark, no email
529 'time' => '2012-03-28 01:00:00',
530 'recipients' => array(),
531 ),
532 array( // After the 2-week mark, send an email
533 'time' => '2012-03-29 01:00:00',
534 'recipients' => array(array('test-member@example.com')),
535 ),
536 ));
537 }
538
539 /**
540 * For contacts/members which match schedule based on join date,
541 * an email should be sent.
542 */
543 function testMembershipJoinDate_NonMatch() {
544 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures['rolling_membership']);
545 $this->assertTrue(is_numeric($membership->id));
bf308d29 546 $result = $this->callAPISuccess('Email', 'create', array(
6a488035
TO
547 'contact_id' => $membership->contact_id,
548 'location_type_id' => 1,
549 'email' => 'test-member@example.com',
6a488035 550 ));
fe265b4e 551
6a488035
TO
552 // Add an alternative membership type, and only send messages for that type
553 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
554 $this->assertTrue(is_numeric($extraMembershipType->id));
cee19268 555 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_membership_join_2week']);
6a488035
TO
556 $this->assertTrue(is_numeric($actionScheduleDao->id));
557 $actionScheduleDao->entity_value = $extraMembershipType->id;
558 $actionScheduleDao->save();
559
560 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
561 $this->assertCronRuns(array(
562 array( // After the 2-week mark, don't send email because we have different membership type
563 'time' => '2012-03-29 01:00:00',
564 'recipients' => array(),
565 ),
566 ));
567 }
568
861d11c4
DG
569 /**
570 * Test that the first and SECOND notifications are sent out
571 *
572 */
573 function testMembershipEndDate_Repeat() {
574 // creates membership with end_date = 20120615
575 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
576 $result = $this->callAPISuccess('Email', 'create', array(
577 'contact_id' => $membership->contact_id,
578 'email' => 'test-member@example.com',
579 ));
580 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
581
582 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
583 $actionSchedule['entity_value'] = $membership->membership_type_id;
584 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
585
586 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
587 $this->assertCronRuns(array(
588 array( // After the 2-week mark, send an email
589 'time' => '2012-08-15 01:00:00',
590 'recipients' => array(array('test-member@example.com')),
591 ),
592 array( // After the 2-week mark, send an email
593 'time' => '2012-09-12 01:00:00',
594 'recipients' => array(array('test-member@example.com')),
595 ),
596 ));
597 }
598
599 /**
600 * Test that the first notification is sent but the second is NOT sent if the end date changes in
601 * between
602 * see CRM-15376
603 */
604 function testMembershipEndDate_Repeat_ChangedEndDate_CRM_15376() {
605 // creates membership with end_date = 20120615
606 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
607 $this->callAPISuccess('Email', 'create', array(
608 'contact_id' => $membership->contact_id,
609 'email' => 'test-member@example.com',
610 ));
611 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
612
613 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
614 $actionSchedule['entity_value'] = $membership->membership_type_id;
615 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
616 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
617 $this->assertCronRuns(array(
618 array( // After the 2-week mark, send an email
619 'time' => '2012-08-15 01:00:00',
620 'recipients' => array(array('test-member@example.com')),
621 ),
622 ));
623
624 //extend membership - reminder should NOT go out
625 $this->callAPISuccess('membership', 'create', array('id' => $membership->id, 'end_date' => '2014-01-01'));
626 $this->assertCronRuns(array(
627 array( // After the 2-week mark, send an email
628 'time' => '2012-09-12 01:00:00',
629 'recipients' => array(),
630 ),
631 ));
632 }
633
6a488035
TO
634 /**
635 * For contacts/members which match schedule based on end date,
636 * an email should be sent.
637 */
638 function testMembershipEndDate_Match() {
639 // creates membership with end_date = 20120615
b29be8c2 640 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
6a488035 641 $this->assertTrue(is_numeric($membership->id));
bf308d29 642 $this->callAPISuccess('Email', 'create', array(
6a488035
TO
643 'contact_id' => $membership->contact_id,
644 'email' => 'test-member@example.com',
bf308d29
EM
645 ));
646 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
6a488035
TO
647
648 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
649 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 650 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
6a488035
TO
651 $this->assertTrue(is_numeric($actionScheduleDao->id));
652
653 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
654 $this->assertCronRuns(array(
655 array( // Before the 2-week mark, no email
656 'time' => '2012-05-31 01:00:00',
657 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
658 'recipients' => array(),
659 ),
660 array( // After the 2-week mark, send an email
661 'time' => '2012-06-01 01:00:00',
662 'recipients' => array(array('test-member@example.com')),
663 ),
664 ));
665 }
666
4b1efa1d 667
668 /**
669 * For contacts/members which match schedule based on end date,
670 * an email should be sent.
671 */
672 function testMembershipEndDate_NoMatch() {
673 // creates membership with end_date = 20120615
674 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership_past'], array('status_id' => 3)));
675 $this->assertTrue(is_numeric($membership->id));
bf308d29 676 $result = $this->callAPISuccess('Email', 'create', array(
4b1efa1d 677 'contact_id' => $membership->contact_id,
678 'email' => 'test-member@example.com',
4b1efa1d 679 ));
bf308d29 680 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
4b1efa1d 681
682 $actionSchedule = $this->fixtures['sched_membership_end_2month'];
683 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 684 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
4b1efa1d 685 $this->assertTrue(is_numeric($actionScheduleDao->id));
686
687 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
688 $this->assertCronRuns(array(
689 array( // Before the 2-week mark, no email
690 'time' => '2012-05-31 01:00:00',
691 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
692 'recipients' => array(),
693 ),
694 array( // After the 2-week mark, send an email
695 'time' => '2013-05-01 01:00:00',
696 'recipients' => array(),
697 ),
698 ));
699 }
700
43030baf 701 function testContactBirthDate_noAnniv() {
bf308d29 702 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
703 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
704 $actionSchedule = $this->fixtures['sched_contact_bday_yesterday'];
705 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
706 $this->assertTrue(is_numeric($actionScheduleDao->id));
707 $this->assertCronRuns(array(
708 array( // On the birthday, no email
709 'time' => '2005-07-07 01:00:00',
710 'recipients' => array(),
711 ),
712 array( // The next day, send an email
713 'time' => '2005-07-08 20:00:00',
714 'recipients' => array(array('test-bday@example.com')),
715 ),
716 ));
717 }
718
719 function testContactBirthDate_Anniv() {
bf308d29 720 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
721 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
722 $actionSchedule = $this->fixtures['sched_contact_bday_anniv'];
723 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
724 $this->assertTrue(is_numeric($actionScheduleDao->id));
725 $this->assertCronRuns(array(
726 array( // On some random day, no email
727 'time' => '2014-03-07 01:00:00',
728 'recipients' => array(),
729 ),
730 array( // On the eve of their 9th birthday, send an email
731 'time' => '2014-07-06 20:00:00',
732 'recipients' => array(array('test-bday@example.com')),
733 ),
734 ));
735 }
4b1efa1d 736
43030baf
AH
737 function testContactCustomDate_noAnniv() {
738 $group = array(
739 'title' => 'Test_Group',
740 'name' => 'test_group',
741 'extends' => array('Individual'),
742 'style' => 'Inline',
743 'is_multiple' => false,
744 'is_active' => 1,
43030baf 745 );
bf308d29 746 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 747 $field = array(
43030baf
AH
748 'label' => 'Graduation',
749 'data_type' => 'Date',
750 'html_type' => 'Select Date',
751 'custom_group_id' => $createGroup['id'],
752 );
bf308d29 753 $createField = $this->callAPISuccess('custom_field', 'create', $field);
43030baf
AH
754 $contactParams = $this->fixtures['contact'];
755 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 756 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
757 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
758 $actionSchedule = $this->fixtures['sched_contact_grad_tomorrow'];
759 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
760 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
761 $this->assertTrue(is_numeric($actionScheduleDao->id));
762 $this->assertCronRuns(array(
763 array( // On some random day, no email
764 'time' => '2014-03-07 01:00:00',
765 'recipients' => array(),
766 ),
767 array( // On the eve of their graduation, send an email
768 'time' => '2013-12-15 20:00:00',
769 'recipients' => array(array('test-member@example.com')),
770 ),
771 ));
bf308d29 772 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id'],));
43030baf 773 }
baa85770
EM
774 /**
775 * Check that limit_to + an empty recipients doesn't sent to multiple contacts
776 */
777 function testMembershipLimitToNone() {
778 // creates membership with end_date = 20120615
779 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
780
781 $this->assertTrue(is_numeric($membership->id));
782 $result = $this->callAPISuccess('Email', 'create', array(
783 'contact_id' => $membership->contact_id,
784 'email' => 'member@example.com',
785 ));
786 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
787 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
788
789 $this->assertAPISuccess($result);
790
791 $actionSchedule = $this->fixtures['sched_membership_end_limit_to_none'];
792 $actionSchedule['entity_value'] = $membership->membership_type_id;
793 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
794 $this->assertTrue(is_numeric($actionScheduleDao->id));
795
796 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
797 $this->assertCronRuns(array(
798 array( // Before the 2-week mark, no email
799 'time' => '2012-05-31 01:00:00',
800 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
801 'recipients' => array(),
802 ),
803 ));
804 }
805
806
43030baf
AH
807
808 function testContactCustomDate_Anniv() {
809 $group = array(
810 'title' => 'Test_Group now',
811 'name' => 'test_group_now',
812 'extends' => array('Individual'),
813 'style' => 'Inline',
814 'is_multiple' => false,
815 'is_active' => 1,
43030baf 816 );
bf308d29 817 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 818 $field = array(
43030baf
AH
819 'label' => 'Graduation',
820 'data_type' => 'Date',
821 'html_type' => 'Select Date',
822 'custom_group_id' => $createGroup['id'],
823 );
bf308d29
EM
824 $createField = $this->callAPISuccess('custom_field', 'create', $field);
825
43030baf
AH
826 $contactParams = $this->fixtures['contact'];
827 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 828 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
829 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
830 $actionSchedule = $this->fixtures['sched_contact_grad_anniv'];
831 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
832 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
833 $this->assertTrue(is_numeric($actionScheduleDao->id));
834 $this->assertCronRuns(array(
835 array( // On some random day, no email
836 'time' => '2014-03-07 01:00:00',
837 'recipients' => array(),
838 ),
839 array( // A week after their 5th anniversary of graduation, send an email
840 'time' => '2018-12-23 20:00:00',
841 'recipients' => array(array('test-member@example.com')),
842 ),
843 ));
bf308d29 844 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id'],));
43030baf 845 }
4b1efa1d 846
6a488035
TO
847 // TODO // function testMembershipEndDate_NonMatch() { }
848 // TODO // function testEventTypeStartDate_Match() { }
849 // TODO // function testEventTypeEndDate_Match() { }
850 // TODO // function testEventNameStartDate_Match() { }
851 // TODO // function testEventNameEndDate_Match() { }
852
853 /**
854 * Run a series of cron jobs and make an assertion about email deliveries
855 *
2a6da8d7
EM
856 * @param $cronRuns
857 *
858 * @internal param array $jobSchedule specifying when to run cron and what messages to expect; each item is an array with keys:
6a488035
TO
859 * - time: string, e.g. '2012-06-15 21:00:01'
860 * - recipients: array(array(string)), list of email addresses which should receive messages
861 */
862 function assertCronRuns($cronRuns) {
863 foreach ($cronRuns as $cronRun) {
864 CRM_Utils_Time::setTime($cronRun['time']);
bf308d29 865 $this->callAPISuccess('job', 'send_reminder', array());
6a488035
TO
866 $this->mut->assertRecipients($cronRun['recipients']);
867 $this->mut->clearMessages();
868 }
869 }
870
871 ////////////////////////////////
872 ////////////////////////////////
873 ////////////////////////////////
874 ////////////////////////////////
875
876 /**
877 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
878 */
879 private $_testObjects;
880
881 /**
882 * Sets up the fixture, for example, opens a network connection.
883 * This method is called before a test is executed.
884 *
885 * @access protected
886 */
887 protected function _setUp() {
888 $this->_testObjects = array();
889 }
890
891 /**
892 * Tears down the fixture, for example, closes a network connection.
893 * This method is called after a test is executed.
894 *
895 * @access protected
896 */
897 protected function _tearDown() {
898 parent::tearDown();
899 $this->deleteTestObjects();
900 }
901
902 /**
903 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
904 * created entities and provides for brainless clenaup.
905 *
906 * @see CRM_Core_DAO::createTestObject
907 */
908 function createTestObject($daoName, $params = array(
909 ), $numObjects = 1, $createOnly = FALSE) {
910 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
911 if (is_array($objects)) {
912 $this->registerTestObjects($objects);
913 } else {
914 $this->registerTestObjects(array($objects));
915 }
916 return $objects;
917 }
918
919 /**
c490a46a 920 * @param $objects array DAO or BAO objects
6a488035
TO
921 */
922 function registerTestObjects($objects) {
923 //if (is_object($objects)) {
924 // $objects = array($objects);
925 //}
926 foreach ($objects as $object) {
927 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
928 $this->_testObjects[$daoName][] = $object->id;
929 }
930 }
931
932 function deleteTestObjects() {
933 // Note: You might argue that the FK relations between test
934 // objects could make this problematic; however, it should
935 // behave intuitively as long as we mentally split our
936 // test-objects between the "manual/primary records"
937 // and the "automatic/secondary records"
938 foreach ($this->_testObjects as $daoName => $daoIds) {
939 foreach ($daoIds as $daoId) {
940 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
941 }
942 }
943 $this->_testObjects = array();
944 }
945
946}