4 * Class CRM_Activity_BAO_ActivityTest
7 class CRM_Activity_BAO_ActivityTest
extends CiviUnitTestCase
{
9 public function setUp() {
11 $this->prepareForACLs();
12 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('view all contacts', 'access CiviCRM');
13 $this->setupForSmsTests();
17 * Clean up after tests.
19 public function tearDown() {
20 $tablesToTruncate = array(
22 'civicrm_activity_contact',
27 $this->quickCleanup($tablesToTruncate);
28 $this->cleanUpAfterACLs();
29 $this->setupForSmsTests(TRUE);
34 * Setup or clean up SMS tests
35 * @param bool $teardown
37 * @throws \CiviCRM_API3_Exception
39 public function setupForSmsTests($teardown = FALSE) {
40 require_once 'CiviTest/CiviTestSMSProvider.php';
42 // Option value params for CiviTestSMSProvider
43 $groupID = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_OptionGroup', 'sms_provider_name', 'id', 'name');
45 'option_group_id' => $groupID,
46 'label' => 'unittestSMS',
47 'value' => 'unit.test.sms',
48 'name' => 'CiviTestSMSProvider',
55 // Test completed, delete provider
56 $providerOptionValueResult = civicrm_api3('option_value', 'get', $params);
57 civicrm_api3('option_value', 'delete', array('id' => $providerOptionValueResult['id']));
61 // Create an SMS provider "CiviTestSMSProvider". Civi handles "CiviTestSMSProvider" as a special case and allows it to be instantiated
62 // in CRM/Sms/Provider.php even though it is not an extension.
63 civicrm_api3('option_value', 'create', $params);
67 * Test case for create() method.
69 public function testCreate() {
70 $contactId = $this->individualCreate();
73 'source_contact_id' => $contactId,
74 'subject' => 'Scheduling Meeting',
75 'activity_type_id' => 2,
78 CRM_Activity_BAO_Activity
::create($params);
80 $activityId = $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting', 'id',
81 'subject', 'Database check for created activity.'
84 // Now call create() to modify an existing Activity.
87 'source_contact_id' => $contactId,
88 'subject' => 'Scheduling Interview',
89 'activity_type_id' => 3,
92 CRM_Activity_BAO_Activity
::create($params);
94 $activityTypeId = $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Interview',
96 'subject', 'Database check on updated activity record.'
98 $this->assertEquals($activityTypeId, 3, 'Verify activity type id is 3.');
100 $this->contactDelete($contactId);
104 * Test case for getContactActivity() method.
106 * getContactActivity() method get activities detail for given target contact id.
108 public function testGetContactActivity() {
109 $contactId = $this->individualCreate();
111 'first_name' => 'liz',
112 'last_name' => 'hurleey',
114 $targetContactId = $this->individualCreate($params);
117 'source_contact_id' => $contactId,
118 'subject' => 'Scheduling Meeting',
119 'activity_type_id' => 2,
120 'target_contact_id' => array($targetContactId),
121 'activity_date_time' => date('Ymd'),
124 $this->callAPISuccess('Activity', 'create', $params);
126 $activityId = $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting',
128 'subject', 'Database check for created activity.'
131 // @todo - remove this deprecated functions
132 $activities = CRM_Activity_BAO_Activity
::getContactActivity($targetContactId);
134 $this->assertEquals($activities[$activityId]['subject'], 'Scheduling Meeting', 'Verify activity subject is correct.');
136 $this->contactDelete($contactId);
137 $this->contactDelete($targetContactId);
141 * Test case for retrieve() method.
143 * Retrieve($params, $defaults) method return activity detail for given params
146 public function testRetrieve() {
147 $contactId = $this->individualCreate();
149 'first_name' => 'liz',
150 'last_name' => 'hurleey',
152 $targetContactId = $this->individualCreate($params);
155 'source_contact_id' => $contactId,
156 'subject' => 'Scheduling Meeting',
157 'activity_type_id' => 2,
158 'target_contact_id' => array($targetContactId),
159 'activity_date_time' => date('Ymd'),
162 CRM_Activity_BAO_Activity
::create($params);
164 $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting', 'id',
165 'subject', 'Database check for created activity.'
168 $this->assertDBNotNull('CRM_Activity_DAO_ActivityContact', $targetContactId,
170 'Database check for created activity target.'
174 $activity = CRM_Activity_BAO_Activity
::retrieve($params, $defaults);
176 $this->assertEquals($activity->subject
, 'Scheduling Meeting', 'Verify activity subject is correct.');
177 $this->assertEquals($activity->activity_type_id
, 2, 'Verify activity type id is correct.');
178 $this->assertEquals($defaults['source_contact_id'], $contactId, 'Verify source contact id is correct.');
180 $this->assertEquals($defaults['subject'], 'Scheduling Meeting', 'Verify activity subject is correct.');
181 $this->assertEquals($defaults['activity_type_id'], 2, 'Verify activity type id is correct.');
183 $this->assertEquals($defaults['target_contact'][0], $targetContactId, 'Verify target contact id is correct.');
185 $this->contactDelete($contactId);
186 $this->contactDelete($targetContactId);
190 * Test case for deleteActivity() method.
192 * deleteActivity($params) method deletes activity for given params.
194 public function testDeleteActivity() {
195 $contactId = $this->individualCreate();
197 'first_name' => 'liz',
198 'last_name' => 'hurleey',
200 $targetContactId = $this->individualCreate($params);
203 'source_contact_id' => $contactId,
204 'source_record_id' => $contactId,
205 'subject' => 'Scheduling Meeting',
206 'activity_type_id' => 2,
207 'target_contact_id' => array($targetContactId),
208 'activity_date_time' => date('Ymd'),
211 CRM_Activity_BAO_Activity
::create($params);
213 $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting', 'id',
214 'subject', 'Database check for created activity.'
217 $this->assertDBNotNull('CRM_Activity_DAO_ActivityContact', $targetContactId,
219 'Database check for created activity target.'
222 'source_contact_id' => $contactId,
223 'source_record_id' => $contactId,
224 'subject' => 'Scheduling Meeting',
225 'activity_type_id' => 2,
228 CRM_Activity_BAO_Activity
::deleteActivity($params);
230 $this->assertDBNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting', 'id',
231 'subject', 'Database check for deleted activity.'
233 $this->contactDelete($contactId);
234 $this->contactDelete($targetContactId);
238 * Test case for deleteActivityTarget() method.
240 * deleteActivityTarget($activityId) method deletes activity target for given activity id.
242 public function testDeleteActivityTarget() {
243 $contactId = $this->individualCreate();
245 'first_name' => 'liz',
246 'last_name' => 'hurleey',
248 $targetContactId = $this->individualCreate($params);
251 'source_contact_id' => $contactId,
252 'subject' => 'Scheduling Meeting',
253 'activity_type_id' => 2,
254 'target_contact_id' => array($targetContactId),
255 'activity_date_time' => date('Ymd'),
258 CRM_Activity_BAO_Activity
::create($params);
260 $activityId = $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting', 'id',
261 'subject', 'Database check for created activity.'
264 $this->assertDBNotNull('CRM_Activity_DAO_ActivityContact', $targetContactId,
266 'Database check for created activity target.'
269 CRM_Activity_BAO_Activity
::deleteActivityContact($activityId, 3);
271 $this->assertDBNull('CRM_Activity_DAO_ActivityContact', $targetContactId, 'id',
272 'contact_id', 'Database check for deleted activity target.'
275 $this->contactDelete($contactId);
276 $this->contactDelete($targetContactId);
280 * Test case for deleteActivityAssignment() method.
282 * deleteActivityAssignment($activityId) method deletes activity assignment for given activity id.
284 public function testDeleteActivityAssignment() {
285 $contactId = $this->individualCreate();
287 'first_name' => 'liz',
288 'last_name' => 'hurleey',
290 $assigneeContactId = $this->individualCreate($params);
293 'source_contact_id' => $contactId,
294 'subject' => 'Scheduling Meeting',
295 'activity_type_id' => 2,
296 'assignee_contact_id' => array($assigneeContactId),
297 'activity_date_time' => date('Ymd'),
300 CRM_Activity_BAO_Activity
::create($params);
302 $activityId = $this->assertDBNotNull('CRM_Activity_DAO_Activity', 'Scheduling Meeting', 'id',
303 'subject', 'Database check for created activity.'
306 $this->assertDBNotNull('CRM_Activity_DAO_ActivityContact',
307 $assigneeContactId, 'id', 'contact_id',
308 'Database check for created activity assignment.'
311 CRM_Activity_BAO_Activity
::deleteActivityContact($activityId, 1);
313 $this->assertDBNull('CRM_Activity_DAO_ActivityContact', $assigneeContactId, 'id',
314 'contact_id', 'Database check for deleted activity assignment.'
317 $this->contactDelete($contactId);
318 $this->contactDelete($assigneeContactId);
322 * Test getActivities BAO method for getting count.
324 public function testGetActivitiesCountForAdminDashboard() {
325 $this->setUpForActivityDashboardTests();
326 $activityCount = CRM_Activity_BAO_Activity
::getActivitiesCount($this->_params
);
327 $this->assertEquals(8, $activityCount);
331 * Test getActivities BAO method for getting count
333 public function testGetActivitiesCountforNonAdminDashboard() {
334 $this->createTestActivities();
341 'activity_type_id' => NULL,
342 // for dashlet the Scheduled status is set by default
343 'activity_status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'status_id', 'Scheduled'),
349 //since we are loading activities from dataset, we know total number of activities for this contact
350 // 5 activities ( 2 scheduled, 3 Completed ), note that dashboard shows only scheduled activities
351 $this->assertEquals(2, CRM_Activity_BAO_Activity
::getActivitiesCount($params));
355 * Test getActivities BAO method for getting count
357 public function testGetActivitiesCountforContactSummary() {
358 $this->createTestActivities();
364 'context' => 'activity',
365 'activity_type_id' => NULL,
371 //since we are loading activities from dataset, we know total number of activities for this contact
372 // 5 activities, Contact Summary should show all activities
373 $this->assertEquals(5, CRM_Activity_BAO_Activity
::getActivitiesCount($params));
377 * CRM-18706 - Test Include/Exclude Activity Filters
379 public function testActivityFilters() {
380 $this->createTestActivities();
381 Civi
::settings()->set('preserve_activity_tab_filter', 1);
382 $this->createLoggedInUser();
387 'context' => 'activity',
388 'activity_type_id' => 1,
391 $expectedFilters = array(
392 'activity_type_filter_id' => 1,
395 list($activities, $activityFilter) = CRM_Activity_Page_AJAX
::getContactActivity();
396 //Assert whether filters are correctly set.
397 $this->checkArrayEquals($expectedFilters, $activityFilter);
398 // This should include activities of type Meeting only.
399 foreach ($activities['data'] as $value) {
400 $this->assertContains('Meeting', $value['activity_type']);
402 unset($_GET['activity_type_id']);
404 $_GET['activity_type_exclude_id'] = $expectedFilters['activity_type_exclude_filter_id'] = 1;
405 list($activities, $activityFilter) = CRM_Activity_Page_AJAX
::getContactActivity();
406 $this->assertEquals(['activity_type_exclude_filter_id' => 1], $activityFilter);
407 // None of the activities should be of type Meeting.
408 foreach ($activities['data'] as $value) {
409 $this->assertNotContains('Meeting', $value['activity_type']);
414 * Test getActivities BAO method for getting count
416 public function testGetActivitiesCountforContactSummaryWithNoActivities() {
417 $this->createTestActivities();
424 'activity_type_id' => NULL,
430 //since we are loading activities from dataset, we know total number of activities for this contact
431 // this contact does not have any activity
432 $this->assertEquals(0, CRM_Activity_BAO_Activity
::getActivitiesCount($params));
436 * Test getActivities BAO method.
438 public function testGetActivitiesForAdminDashboard() {
439 $this->setUpForActivityDashboardTests();
440 $activitiesNew = CRM_Activity_BAO_Activity
::getActivities($this->_params
);
441 // $this->assertEquals($activities, $activitiesDeprecatedFn);
443 //since we are loading activities from dataset, we know total number of activities
444 // with no contact ID and there should be 8 schedule activities shown on dashboard
446 foreach (array($activitiesNew) as $activities) {
447 $this->assertEquals($count, count($activities));
449 foreach ($activities as $key => $value) {
450 $this->assertEquals($value['subject'], "subject {$key}", 'Verify activity subject is correct.');
451 $this->assertEquals($value['activity_type_id'], 2, 'Verify activity type is correct.');
452 $this->assertEquals($value['status_id'], 1, 'Verify all activities are scheduled.');
458 * Test getActivities BAO method.
460 public function testGetActivitiesForAdminDashboardNoViewContacts() {
461 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
462 $this->setUpForActivityDashboardTests();
463 foreach (array(CRM_Activity_BAO_Activity
::getActivities($this->_params
)) as $activities) {
464 // Skipped until we get back to the upgraded version properly.
465 $this->assertEquals(0, count($activities));
470 * Test getActivities BAO method.
472 public function testGetActivitiesForAdminDashboardAclLimitedViewContacts() {
473 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM');
474 $this->allowedContacts
= array(1, 3, 4, 5);
475 $this->hookClass
->setHook('civicrm_aclWhereClause', array($this, 'aclWhereMultipleContacts'));
476 $this->setUpForActivityDashboardTests();
477 $this->assertEquals(7, count(CRM_Activity_BAO_Activity
::getActivities($this->_params
)));
481 * Test getActivities BAO method.
483 public function testGetActivitiesforNonAdminDashboard() {
484 $this->createTestActivities();
488 'contact_id' => $contactID,
492 'activity_type_id' => NULL,
493 // for dashlet the Scheduled status is set by default
494 'activity_status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'status_id', 'Scheduled'),
500 foreach (array(CRM_Activity_BAO_Activity
::getActivities($params)) as $activities) {
501 //since we are loading activities from dataset, we know total number of activities for this contact
502 // 5 activities ( 2 scheduled, 3 Completed ), note that dashboard shows only scheduled activities
504 $this->assertEquals($count, count($activities));
506 foreach ($activities as $key => $value) {
507 $this->assertEquals($value['subject'], "subject {$key}", 'Verify activity subject is correct.');
508 $this->assertEquals($value['activity_type_id'], 2, 'Verify activity type is correct.');
509 $this->assertEquals($value['status_id'], 1, 'Verify all activities are scheduled.');
512 $this->assertArrayHasKey($contactID, $value['target_contact_name']);
515 $this->assertArrayHasKey($contactID, $value['assignee_contact_name']);
522 * Test target contact count.
524 public function testTargetCountforContactSummary() {
526 $contactId = $this->individualCreate();
527 $targetContactIDs = array();
528 for ($i = 0; $i < $targetCount; $i++
) {
529 $targetContactIDs[] = $this->individualCreate(array(), $i);
531 // Create activities with 5 target contacts.
532 $activityParams = array(
533 'source_contact_id' => $contactId,
534 'target_contact_id' => $targetContactIDs,
536 $this->activityCreate($activityParams);
539 'contact_id' => $contactId,
540 'context' => 'activity',
542 $activities = CRM_Activity_BAO_Activity
::getActivities($params);
543 //verify target count
544 $this->assertEquals($targetCount, $activities[1]['target_contact_count']);
545 $this->assertEquals([$targetContactIDs[0] => 'Anderson, Anthony'], $activities[1]['target_contact_name']);
546 $this->assertEquals('Anderson, Anthony', $activities[1]['source_contact_name']);
547 $this->assertEquals('Anderson, Anthony', $activities[1]['assignee_contact_name'][4]);
551 * Test getActivities BAO method.
553 public function testGetActivitiesforContactSummaryWithSortOptions() {
554 $this->createTestActivities();
559 'context' => 'activity',
560 'activity_type_id' => NULL,
563 'sort' => 'source_contact_name desc',
566 $activities = CRM_Activity_BAO_Activity
::getActivities($params);
567 $alphaOrder = ['Test Contact 11', 'Test Contact 12', 'Test Contact 3', 'Test Contact 4', 'Test Contact 9'];
568 foreach ($activities as $activity) {
569 $this->assertEquals(array_pop($alphaOrder), $activity['source_contact_name']);
575 * Test getActivities BAO method.
577 public function testGetActivitiesForContactSummary() {
578 $this->createTestActivities();
582 'contact_id' => $contactID,
585 'context' => 'activity',
586 'activity_type_id' => NULL,
591 //since we are loading activities from dataset, we know total number of activities for this contact
592 // 5 activities, Contact Summary should show all activities
594 $activities = CRM_Activity_BAO_Activity
::getActivities($params);
595 $this->assertEquals($count, count($activities));
596 foreach ($activities as $key => $value) {
597 $this->assertEquals($value['subject'], "subject {$key}", 'Verify activity subject is correct.');
600 $this->assertEquals($value['status_id'], 2, 'Verify all activities are scheduled.');
603 $this->assertEquals($value['status_id'], 1, 'Verify all activities are scheduled.');
607 $this->assertEquals($value['activity_type'], 'Bulk Email', 'Verify activity type is correct.');
608 $this->assertEquals('(2 recipients)', $value['recipients']);
609 $targetContactID = key($value['target_contact_name']);
610 // The 2 targets have ids 10 & 11. Since they are not sorted it could be either on some systems.
611 $this->assertTrue(in_array($targetContactID, [10, 11]));
614 $this->assertEquals($value['activity_type_id'], 1, 'Verify activity type is correct.');
617 $this->assertEquals($value['activity_type_id'], 2, 'Verify activity type is correct.');
621 $this->assertEquals([$contactID => 'Test Contact ' . $contactID], $value['target_contact_name']);
624 $this->assertArrayHasKey($contactID, $value['assignee_contact_name']);
630 * Test getActivities BAO method.
632 public function testGetActivitiesforContactSummaryWithActivities() {
633 $this->createTestActivities();
635 // parameters for different test cases, check each array key for the specific test-case
637 'with-no-activity' => array(
643 'activity_type_id' => NULL,
649 'with-activity' => array(
655 'activity_type_id' => NULL,
661 'with-activity_type' => array(
667 'activity_type_id' => 2,
673 'exclude-all-activity_type' => array(
679 'activity_type_exclude_id' => array(1, 2),
685 'sort-by-subject' => array(
691 'activity_type_id' => NULL,
694 'sort' => 'subject DESC',
699 foreach ($testCases as $caseName => $testCase) {
700 $activityCount = CRM_Activity_BAO_Activity
::getActivitiesCount($testCase['params']);
701 $activitiesNew = CRM_Activity_BAO_Activity
::getActivities($testCase['params']);
703 foreach (array($activitiesNew) as $activities) {
704 //$this->assertEquals($activityCount, CRM_Activity_BAO_Activity::getActivitiesCount($testCase['params']));
705 if ($caseName == 'with-no-activity') {
706 $this->assertEquals(0, count($activities));
707 $this->assertEquals(0, $activityCount);
709 elseif ($caseName == 'with-activity') {
710 // contact id 1 is assigned as source, target and assignee for activity id 1, 7 and 8 respectively
711 $this->assertEquals(3, count($activities));
712 $this->assertEquals(3, $activityCount);
713 $this->assertEquals(1, $activities[1]['source_contact_id']);
714 // @todo - this is a discrepancy between old & new - review.
715 //$this->assertEquals(TRUE, array_key_exists(1, $activities[7]['target_contact_name']));
716 $this->assertEquals(TRUE, array_key_exists(1, $activities[8]['assignee_contact_name']));
718 elseif ($caseName == 'with-activity_type') {
719 // contact id 3 for activity type 2 is assigned as assignee, source and target for
720 // activity id 1, 3 and 8 respectively
721 $this->assertEquals(3, count($activities));
722 $this->assertEquals(3, $activityCount);
723 // ensure activity type id is 2
724 $this->assertEquals(2, $activities[1]['activity_type_id']);
725 $this->assertEquals(3, $activities[3]['source_contact_id']);
726 // @todo review inconsistency between 2 versions.
727 // $this->assertEquals(TRUE, array_key_exists(3, $activities[8]['target_contact_name']));
728 $this->assertEquals(TRUE, array_key_exists(3, $activities[1]['assignee_contact_name']));
730 if ($caseName == 'exclude-all-activity_type') {
731 $this->assertEquals(0, count($activities));
732 $this->assertEquals(0, $activityCount);
734 if ($caseName == 'sort-by-subject') {
735 $this->assertEquals(3, count($activities));
736 $this->assertEquals(3, $activityCount);
737 // activities should be order by 'subject DESC'
738 $subjectOrder = array(
744 foreach ($activities as $activity) {
745 $this->assertEquals($subjectOrder[$count], $activity['subject']);
754 * CRM-20793 : Test getActivities by using activity date and status filter
756 public function testByActivityDateAndStatus() {
757 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= ['view all contacts', 'access CiviCRM'];
758 $this->createTestActivities();
760 // activity IDs catagorised by date
761 $lastWeekActivities = array(1, 2, 3);
762 $todayActivities = array(4, 5, 6, 7);
763 $lastTwoMonthsActivities = array(8, 9, 10, 11);
764 $lastOrNextYearActivities = array(12, 13, 14, 15, 16);
766 // date values later used to set activity date value
767 $lastWeekDate = date('YmdHis', strtotime('1 week ago'));
768 $today = date('YmdHis');
769 $lastTwoMonthAgoDate = date('YmdHis', strtotime('2 months ago'));
770 // if current month is Jan then choose next year date otherwise the search result will include
771 // the previous week and last two months activities which are still in previous year and hence leads to improper result
772 $lastOrNextYearDate = (date('M') == 'Jan') ?
date('YmdHis', strtotime('+1 year')) : date('YmdHis', strtotime('1 year ago'));
773 for ($i = 1; $i <= 16; $i++
) {
774 if (in_array($i, $lastWeekActivities)) {
775 $date = $lastWeekDate;
777 elseif (in_array($i, $lastTwoMonthsActivities)) {
778 $date = $lastTwoMonthAgoDate;
780 elseif (in_array($i, $lastOrNextYearActivities)) {
781 $date = $lastOrNextYearDate;
783 elseif (in_array($i, $todayActivities)) {
786 $this->callAPISuccess('Activity', 'create', array(
788 'activity_date_time' => $date,
792 // parameters for different test cases, check each array key for the specific test-case
794 'todays-activity' => array(
799 'context' => 'activity',
800 'activity_date_time_relative' => 'this.day',
801 'activity_type_id' => NULL,
807 'todays-activity-filtered-by-range' => array(
812 'context' => 'activity',
813 'activity_date_time_low' => date('Y/m/d', strtotime('yesterday')),
814 'activity_date_time_high' => date('Y/m/d'),
815 'activity_type_id' => NULL,
821 'last-week-activity' => array(
826 'context' => 'activity',
827 'activity_date_time_relative' => 'previous.week',
828 'activity_type_id' => NULL,
834 'this-quarter-activity' => array(
839 'context' => 'activity',
840 'activity_date_time_relative' => 'this.quarter',
841 'activity_type_id' => NULL,
847 'activity-of-all-statuses' => array(
852 'context' => 'activity',
853 'activity_status_id' => '1,2',
854 'activity_type_id' => NULL,
862 foreach ($testCases as $caseName => $testCase) {
863 CRM_Utils_Date
::convertFormDateToApiFormat($testCase['params'], 'activity_date_time', FALSE);
864 $activities = CRM_Activity_BAO_Activity
::getActivities($testCase['params']);
865 $activityCount = CRM_Activity_BAO_Activity
::getActivitiesCount($testCase['params']);
867 $activityIDs = array_keys($activities);
869 if ($caseName == 'todays-activity' ||
$caseName == 'todays-activity-filtered-by-range') {
870 // Only one of the 4 activities today relates to contact id 1.
871 $this->assertEquals(1, $activityCount);
872 $this->assertEquals(1, count($activities));
873 $this->assertEquals([7], array_keys($activities));
875 elseif ($caseName == 'last-week-activity') {
876 // Only one of the 3 activities today relates to contact id 1.
877 $this->assertEquals(1, $activityCount);
878 $this->assertEquals(1, count($activities));
879 $this->assertEquals([1], $activityIDs);
881 elseif ($caseName == 'lhis-quarter-activity') {
882 $this->assertEquals(count($lastTwoMonthsActivities), $activityCount);
883 $this->assertEquals(count($lastTwoMonthsActivities), count($activities));
884 $this->checkArrayEquals($lastTwoMonthsActivities, $activityIDs);
886 elseif ($caseName == 'last-or-next-year-activity') {
887 $this->assertEquals(count($lastOrNextYearActivities), $activityCount);
888 $this->assertEquals(count($lastOrNextYearActivities), count($activities));
889 $this->checkArrayEquals($lastOrNextYearActivities, $activityIDs);
891 elseif ($caseName == 'activity-of-all-statuses') {
892 $this->assertEquals(3, $activityCount);
893 $this->assertEquals(3, count($activities));
899 * @dataProvider getActivityDateData
901 public function testActivityRelativeDateFilter($params, $expected) {
902 $thisYear = date('Y');
904 date('Y-m-d', strtotime(($thisYear - 1) . '-01-01')),
905 date('Y-m-d', strtotime(($thisYear - 1) . '-12-31')),
906 date('Y-m-d', strtotime($thisYear . '-01-01')),
907 date('Y-m-d', strtotime($thisYear . '-12-31')),
908 date('Y-m-d', strtotime(($thisYear +
1) . '-01-01')),
909 date('Y-m-d', strtotime(($thisYear +
1) . '-12-31')),
911 foreach ($dates as $date) {
912 $this->activityCreate(['activity_date_time' => $date]);
914 $activitiesDep = CRM_Activity_BAO_Activity
::getActivities($params);
915 $activityCount = CRM_Activity_BAO_Activity
::getActivitiesCount($params);
916 $this->assertEquals(count($activitiesDep), $activityCount);
917 foreach ($activitiesDep as $activity) {
918 $this->assertTrue(strtotime($activity['activity_date_time']) >= $expected['earliest'], $activity['activity_date_time'] . ' should be no earlier than ' . date('Y-m-d H:i:s', $expected['earliest']));
919 $this->assertTrue(strtotime($activity['activity_date_time']) < $expected['latest'], $activity['activity_date_time'] . ' should be before ' . date('Y-m-d H:i:s', $expected['latest']));
925 * Get activity date data.
927 * Later we might migrate rework the rest of
928 * testByActivityDateAndStatus
929 * to use data provider methodology as it's way complex!
933 public function getActivityDateData() {
935 'last-year-activity' => [
940 'context' => 'activity',
941 'activity_date_relative' => 'previous.year',
942 'activity_type_id' => NULL,
949 'earliest' => strtotime('first day of january last year'),
950 'latest' => strtotime('first day of january this year'),
957 * CRM-20308: Test from email address when a 'copy of Activity' event occur
959 public function testEmailAddressOfActivityCopy() {
960 // Case 1: assert the 'From' Email Address of source Actvity Contact ID
961 // create activity with source contact ID which has email address
962 $assigneeContactId = $this->individualCreate();
963 $sourceContactParams = array(
964 'first_name' => 'liz',
965 'last_name' => 'hurleey',
966 'email' => substr(sha1(rand()), 0, 7) . '@testemail.com',
968 $sourceContactID = $this->individualCreate($sourceContactParams);
969 $sourceDisplayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact', $sourceContactID, 'display_name');
971 // create an activity using API
973 'source_contact_id' => $sourceContactID,
974 'subject' => 'Scheduling Meeting ' . substr(sha1(rand()), 0, 4),
975 'activity_type_id' => CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Meeting'),
976 'assignee_contact_id' => array($assigneeContactId),
977 'activity_date_time' => date('Ymd'),
979 $activity = $this->callAPISuccess('Activity', 'create', $params);
981 // Check that from address is in "Source-Display-Name <source-email>"
982 $formAddress = CRM_Case_BAO_Case
::getReceiptFrom($activity['id']);
983 $expectedFromAddress = sprintf("%s <%s>", $sourceDisplayName, $sourceContactParams['email']);
984 $this->assertEquals($expectedFromAddress, $formAddress);
986 // Case 2: System Default From Address
987 // but first erase the email address of existing source contact ID
988 $withoutEmailParams = array(
991 $sourceContactID = $this->individualCreate($withoutEmailParams);
993 'source_contact_id' => $sourceContactID,
994 'subject' => 'Scheduling Meeting ' . substr(sha1(rand()), 0, 4),
995 'activity_type_id' => CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Meeting'),
996 'activity_date_time' => date('Ymd'),
998 $activity = $this->callAPISuccess('Activity', 'create', $params);
1000 $domainInfo = $this->callAPISuccess('Domain', 'getsingle', array('id' => CRM_Core_Config
::domainID()));
1002 $formAddress = CRM_Case_BAO_Case
::getReceiptFrom($activity['id']);
1003 if (!empty($domainInfo['from_email'])) {
1004 $expectedFromAddress = sprintf("%s <%s>", $domainInfo['from_name'], $domainInfo['from_email']);
1006 // Case 3: fetch default Organization Contact email address
1007 elseif (!empty($domainInfo['domain_email'])) {
1008 $expectedFromAddress = sprintf("%s <%s>", $domainInfo['name'], $domainInfo['domain_email']);
1010 $this->assertEquals($expectedFromAddress, $formAddress);
1012 // TODO: Case 4 about checking the $formAddress on basis of logged contact ID respectively needs,
1013 // to change the domain setting, which isn't straight forward in test environment
1017 * Set up for testing activity queries.
1019 protected function setUpForActivityDashboardTests() {
1020 $this->createTestActivities();
1022 $this->_params
= array(
1023 'contact_id' => NULL,
1026 'context' => 'home',
1027 'activity_type_id' => NULL,
1028 // for dashlet the Scheduled status is set by default
1029 'activity_status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'status_id', 'Scheduled'),
1036 public function testSendEmailBasic() {
1037 $contactId = $this->individualCreate();
1039 // create a logged in USER since the code references it for sendEmail user.
1040 $this->createLoggedInUser();
1041 $session = CRM_Core_Session
::singleton();
1042 $loggedInUser = $session->get('userID');
1044 $contact = $this->civicrm_api('contact', 'getsingle', array('id' => $contactId, 'version' => $this->_apiversion
));
1045 $contactDetailsIntersectKeys = array(
1048 'display_name' => '',
1049 'do_not_email' => '',
1050 'preferred_mail_format' => '',
1051 'is_deceased' => '',
1055 $contactDetails = array(
1056 array_intersect_key($contact, $contactDetailsIntersectKeys),
1059 $subject = __FUNCTION__
. ' subject';
1060 $html = __FUNCTION__
. ' html';
1061 $text = __FUNCTION__
. ' text';
1062 $userID = $loggedInUser;
1064 list($sent, $activity_id) = $email_result = CRM_Activity_BAO_Activity
::sendEmail(
1071 $from = __FUNCTION__
. '@example.com'
1074 $activity = $this->civicrm_api('activity', 'getsingle', array('id' => $activity_id, 'version' => $this->_apiversion
));
1075 $details = "-ALTERNATIVE ITEM 0-
1077 -ALTERNATIVE ITEM 1-
1081 $this->assertEquals($activity['details'], $details, 'Activity details does not match.');
1082 $this->assertEquals($activity['subject'], $subject, 'Activity subject does not match.');
1085 public function testSendEmailWithCampaign() {
1086 // Create a contact and contactDetails array.
1087 $contactId = $this->individualCreate();
1089 // create a logged in USER since the code references it for sendEmail user.
1090 $this->createLoggedInUser();
1091 $session = CRM_Core_Session
::singleton();
1092 $loggedInUser = $session->get('userID');
1094 $contact = $this->civicrm_api('contact', 'getsingle', array('id' => $contactId, 'version' => $this->_apiversion
));
1095 $contactDetailsIntersectKeys = array(
1098 'display_name' => '',
1099 'do_not_email' => '',
1100 'preferred_mail_format' => '',
1101 'is_deceased' => '',
1105 $contactDetails = array(
1106 array_intersect_key($contact, $contactDetailsIntersectKeys),
1109 // Create a campaign.
1110 $result = $this->civicrm_api('Campaign', 'create', array(
1111 'version' => $this->_apiversion
,
1112 'title' => __FUNCTION__
. ' campaign',
1114 $campaign_id = $result['id'];
1116 $subject = __FUNCTION__
. ' subject';
1117 $html = __FUNCTION__
. ' html';
1118 $text = __FUNCTION__
. ' text';
1119 $userID = $loggedInUser;
1121 list($sent, $activity_id) = $email_result = CRM_Activity_BAO_Activity
::sendEmail(
1128 $from = __FUNCTION__
. '@example.com',
1129 $attachments = NULL,
1133 $additionalDetails = NULL,
1137 $activity = $this->civicrm_api('activity', 'getsingle', array('id' => $activity_id, 'version' => $this->_apiversion
));
1138 $this->assertEquals($activity['campaign_id'], $campaign_id, 'Activity campaign_id does not match.');
1142 * @expectedException CRM_Core_Exception
1143 * @expectedExceptionMessage You do not have the 'send SMS' permission
1145 public function testSendSMSWithoutPermission() {
1147 $session = CRM_Core_Session
::singleton();
1148 $config = &CRM_Core_Config
::singleton();
1149 $config->userPermissionClass
->permissions
= array('access CiviCRM');
1151 CRM_Activity_BAO_Activity
::sendSMS(
1156 $session->get('userID')
1160 public function testSendSmsNoPhoneNumber() {
1161 list($sent, $activityId, $success) = $this->createSendSmsTest(0);
1162 $activity = $this->civicrm_api('activity', 'getsingle', array('id' => $activityId, 'version' => $this->_apiversion
));
1164 $outBoundSmsActivityId = CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'SMS');
1165 $activityStatusCompleted = CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Completed');
1166 $details = 'createSendSmsTest text';
1167 $this->assertEquals($activity['activity_type_id'], $outBoundSmsActivityId, 'Wrong activity type is set.');
1168 $this->assertEquals($activity['status_id'], $activityStatusCompleted, 'Expected activity status Completed.');
1169 $this->assertEquals($activity['subject'], 'createSendSmsTest subject', 'Activity subject does not match.');
1170 $this->assertEquals($activity['details'], $details, 'Activity details does not match.');
1171 $this->assertEquals("Recipient phone number is invalid or recipient does not want to receive SMS", $sent[0]->message
, "Expected error doesn't match");
1172 $this->assertEquals(0, $success, "Expected success to be 0");
1175 public function testSendSmsFixedPhoneNumber() {
1176 list($sent, $activityId, $success) = $this->createSendSmsTest(1);
1177 $activity = $this->civicrm_api('activity', 'getsingle', array('id' => $activityId, 'version' => $this->_apiversion
));
1179 $outBoundSmsActivityId = CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'SMS');
1180 $activityStatusCompleted = CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Completed');
1181 $details = 'createSendSmsTest text';
1182 $this->assertEquals($activity['activity_type_id'], $outBoundSmsActivityId, 'Wrong activity type is set.');
1183 $this->assertEquals($activity['status_id'], $activityStatusCompleted, 'Expected activity status Completed.');
1184 $this->assertEquals($activity['subject'], 'createSendSmsTest subject', 'Activity subject does not match.');
1185 $this->assertEquals($activity['details'], $details, 'Activity details does not match.');
1186 $this->assertEquals("Recipient phone number is invalid or recipient does not want to receive SMS", $sent[0]->message
, "Expected error doesn't match");
1187 $this->assertEquals(0, $success, "Expected success to be 0");
1190 public function testSendSmsMobilePhoneNumber() {
1191 list($sent, $activityId, $success) = $this->createSendSmsTest(2);
1192 $activity = $this->civicrm_api('activity', 'getsingle', array('id' => $activityId, 'version' => $this->_apiversion
));
1194 $outBoundSmsActivityId = CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'SMS');
1195 $activityStatusCompleted = CRM_Core_PseudoConstant
::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Completed');
1196 $details = 'createSendSmsTest text';
1197 $this->assertEquals($activity['activity_type_id'], $outBoundSmsActivityId, 'Wrong activity type is set.');
1198 $this->assertEquals($activity['status_id'], $activityStatusCompleted, 'Expected activity status Completed.');
1199 $this->assertEquals($activity['subject'], 'createSendSmsTest subject', 'Activity subject does not match.');
1200 $this->assertEquals($activity['details'], $details, 'Activity details does not match.');
1201 $this->assertEquals(TRUE, $sent, "Expected sent should be true");
1202 $this->assertEquals(1, $success, "Expected success to be 1");
1206 * Test that when a numbe ris specified in the To Param of the SMS provider parameters that an SMS is sent
1207 * @see dev/core/#273
1209 public function testSendSMSMobileInToProviderParam() {
1210 list($sent, $activityId, $success) = $this->createSendSmsTest(2, TRUE);
1211 $this->assertEquals(TRUE, $sent, "Expected sent should be true");
1212 $this->assertEquals(1, $success, "Expected success to be 1");
1216 * Test that when a numbe ris specified in the To Param of the SMS provider parameters that an SMS is sent
1217 * @see dev/core/#273
1219 public function testSendSMSMobileInToProviderParamWithDoNotSMS() {
1220 list($sent, $activityId, $success) = $this->createSendSmsTest(2, TRUE, ['do_not_sms' => 1]);
1221 foreach ($sent as $error) {
1222 $this->assertEquals('Contact Does not accept SMS', $error->getMessage());
1224 $this->assertEquals(1, count($sent), "Expected sent should a PEAR Error");
1225 $this->assertEquals(0, $success, "Expected success to be 0");
1229 * @param int $phoneType (0=no phone, phone_type option group (1=fixed, 2=mobile)
1230 * @param bool $passPhoneTypeInContactDetails
1231 * @param array $additionalContactParams additional contact creation params
1233 public function createSendSmsTest($phoneType = 0, $passPhoneTypeInContactDetails = FALSE, $additionalContactParams = []) {
1234 $provider = civicrm_api3('SmsProvider', 'create', array(
1235 'name' => "CiviTestSMSProvider",
1241 "api_params" => "a=1",
1242 "is_default" => "1",
1247 $smsProviderParams['provider_id'] = $provider['id'];
1250 $contactId = $this->individualCreate();
1251 if (!empty($additionalContactParams)) {
1252 $this->callAPISuccess('contact', 'create', ['id' => $contactId] +
$additionalContactParams);
1254 $contactsResult = $this->callApiSuccess('contact', 'get', ['id' => $contactId, 'version' => $this->_apiversion
]);
1255 $contactDetails = $contactsResult['values'];
1257 // Get contactIds from contact details
1258 foreach ($contactDetails as $contact) {
1259 $contactIds[] = $contact['contact_id'];
1262 $activityParams['sms_text_message'] = __FUNCTION__
. ' text';
1263 $activityParams['activity_subject'] = __FUNCTION__
. ' subject';
1265 // Get a "logged in" user to set as source of Sms.
1266 $session = CRM_Core_Session
::singleton();
1267 $sourceContactId = $session->get('userID');
1270 $this->_testSmsContactId
= $this->createLoggedInUser();
1272 // Give user permission to 'send SMS'
1273 CRM_Core_Config
::singleton()->userPermissionClass
->permissions
= array('access CiviCRM', 'send SMS');
1275 // Create a phone number
1276 switch ($phoneType) {
1282 // Create a mobile phone number
1283 $phone = civicrm_api3('Phone', 'create', array(
1284 'contact_id' => $contactId,
1286 'phone_type_id' => "Mobile",
1288 if ($passPhoneTypeInContactDetails) {
1289 $contactDetails[$contactId]['phone'] = $phone['values'][$phone['id']]['phone'];
1290 $contactDetails[$contactId]['phone_type_id'] = $phone['values'][$phone['id']]['phone_type_id'];
1295 // Create a fixed phone number
1296 $phone = civicrm_api3('Phone', 'create', array(
1297 'contact_id' => $contactId,
1299 'phone_type_id' => "Phone",
1301 if ($passPhoneTypeInContactDetails) {
1302 $contactDetails[$contactId]['phone'] = $phone['values'][$phone['id']]['phone'];
1303 $contactDetails[$contactId]['phone_type_id'] = $phone['values'][$phone['id']]['phone_type_id'];
1308 // Now run the actual test
1309 list($sent, $activityId, $success) = CRM_Activity_BAO_Activity
::sendSms(
1317 return array($sent, $activityId, $success);
1320 protected function createTestActivities() {
1321 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1322 $op->execute($this->_dbconn
,
1323 $this->createFlatXMLDataSet(
1324 dirname(__FILE__
) . '/activities_for_dashboard_count.xml'
1327 // Make changes to improve variation in php since the xml method is brittle & relies on option values being unchanged.
1328 $this->callAPISuccess('Activity', 'create', ['id' => 12, 'activity_type_id' => 'Bulk Email']);