$this->assertEmpty($msg);
}
+ public function testActivityDelete() {
+ // Set the parameters of the test.
+ $numberOfSingleActivitiesToCreate = 3;
+ $numberOfRepeatingActivitiesToCreate = 6;
+ $singleActivityToDeleteOffset = 1;
+ $mode1ActivityToDeleteOffset = 1;
+ $mode2ActivityToDeleteOffset = 3;
+ $mode3ActivityToDeleteOffset = 2;
+
+ // Track the target contact's activities.
+ $expectedActivityIds = array_keys(CRM_Activity_BAO_Activity::getActivities(['contact_id' => $this->target]));
+
+ // Create non-repeating activities.
+ $meetingActivityTypeId = CRM_Core_PseudoConstant::getKey('CRM_Activity_DAO_Activity', 'activity_type_id', 'Meeting');
+ $singleActivityIds = [];
+ for ($activityCount = 0; $activityCount < $numberOfSingleActivitiesToCreate; $activityCount++) {
+ $activityParams = [
+ 'source_contact_id' => $this->source,
+ 'target_contact_id' => $this->target,
+ 'activity_type_id' => $meetingActivityTypeId,
+ 'activity_date_time' => date_create('+' . $activityCount . ' weeks')->format('YmdHis'),
+ ];
+ $singleActivityBao = CRM_Activity_BAO_Activity::create($activityParams);
+ $singleActivityIds[] = $singleActivityBao->id;
+ }
+ $expectedActivityIds = array_merge($expectedActivityIds, $singleActivityIds);
+
+ // Create an activity to be repeated.
+ $activityParams = [
+ 'source_contact_id' => $this->source,
+ 'target_contact_id' => $this->target,
+ 'activity_type_id' => $meetingActivityTypeId,
+ 'activity_date_time' => date('YmdHis'),
+ ];
+ $repeatingActivityBao = CRM_Activity_BAO_Activity::create($activityParams);
+
+ // Create the repeating activity's schedule.
+ $actionScheduleParams = [
+ 'used_for' => 'civicrm_activity',
+ 'entity_value' => $repeatingActivityBao->id,
+ 'start_action_date' => $repeatingActivityBao->activity_date_time,
+ 'repetition_frequency_unit' => 'week',
+ 'repetition_frequency_interval' => 1,
+ 'start_action_offset' => $numberOfRepeatingActivitiesToCreate - 1,
+ ];
+ $actionScheduleBao = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
+
+ // Create the activity's repeats.
+ $recurringEntityBao = new CRM_Core_BAO_RecurringEntity();
+ $recurringEntityBao->entity_table = 'civicrm_activity';
+ $recurringEntityBao->entity_id = $repeatingActivityBao->id;
+ $recurringEntityBao->dateColumns = ['activity_date_time'];
+ $recurringEntityBao->linkedEntities = [
+ [
+ 'table' => 'civicrm_activity_contact',
+ 'findCriteria' => ['activity_id' => $repeatingActivityBao->id],
+ 'linkedColumns' => ['activity_id'],
+ 'isRecurringEntityRecord' => FALSE,
+ ],
+ ];
+ $recurringEntityBao->scheduleId = $actionScheduleBao->id;
+ $newEntities = $recurringEntityBao->generate();
+ $repeatingActivityIds = array_merge([$repeatingActivityBao->id], $newEntities['civicrm_activity']);
+ $expectedActivityIds = array_merge($expectedActivityIds, $repeatingActivityIds);
+
+ // Assert that the expected activities exist.
+ $this->assertTargetActivityIds($expectedActivityIds);
+
+ // Delete a non-repeating activity.
+ $activityId = $singleActivityIds[$singleActivityToDeleteOffset];
+ $this->deleteActivity($activityId);
+ $expectedActivityIds = array_diff($expectedActivityIds, [$activityId]);
+ $this->assertTargetActivityIds($expectedActivityIds);
+
+ // Delete one activity from series (mode 1).
+ $activityId = $repeatingActivityIds[$mode1ActivityToDeleteOffset];
+ $this->deleteActivity($activityId, 1);
+ $expectedActivityIds = array_diff($expectedActivityIds, [$activityId]);
+ $this->assertTargetActivityIds($expectedActivityIds);
+
+ // Delete from one activity until end of series (mode 2).
+ $activityId = $repeatingActivityIds[$mode2ActivityToDeleteOffset];
+ $this->deleteActivity($activityId, 2);
+ $expectedActivityIds = array_diff($expectedActivityIds, array_slice($repeatingActivityIds, $mode2ActivityToDeleteOffset));
+ $this->assertTargetActivityIds($expectedActivityIds);
+
+ // Delete all activities in series (mode 3).
+ $activityId = $repeatingActivityIds[$mode3ActivityToDeleteOffset];
+ $this->deleteActivity($activityId, 3);
+ $expectedActivityIds = array_diff($expectedActivityIds, $repeatingActivityIds);
+ $this->assertTargetActivityIds($expectedActivityIds);
+ }
+
+ /**
+ * Asserts that the target contact has the expected activity IDs
+ *
+ * @param array $expectedActivityIds
+ * An array of the activity IDs that are expected to exist for the target contact
+ */
+ private function assertTargetActivityIds($expectedActivityIds) {
+ $actualActivityIds = array_keys(CRM_Activity_BAO_Activity::getActivities(['contact_id' => $this->target]));
+ $this->assertEquals(array_fill_keys($expectedActivityIds, NULL), array_fill_keys($actualActivityIds, NULL));
+ }
+
+ /**
+ * Tests the form's deletion of activities, with optional mode for repeating activities
+ *
+ * @param int $activityId
+ * The ID of the activity to delete
+ * @param int $mode
+ * 1 - delete the specified activity
+ * 2 - delete the specified activity and all following activities in the series
+ * 3 - delete all activities in the series
+ */
+ private function deleteActivity($activityId, $mode = NULL) {
+ // For repeating activities, set the recurring entity mode.
+ if (!is_null($mode)) {
+ $recurringEntityBao = new CRM_Core_BAO_RecurringEntity();
+ $recurringEntityBao->entity_table = 'civicrm_activity';
+ $recurringEntityBao->entity_id = $activityId;
+ $recurringEntityBao->mode($mode);
+ }
+
+ // Use a form to delete the activity.
+ $form = new CRM_Activity_Form_Activity();
+ $form->_action = CRM_Core_Action::DELETE;
+ $form->_activityId = $activityId;
+ $form->postProcess();
+ }
+
}