move statusBounce out of BAO layer; don't allow self-service when disabled; support...
[civicrm-core.git] / tests / phpunit / CRM / Event / BAO / ParticipantTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7d61e75f 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
7d61e75f
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035 11
4cbe18b8
EM
12/**
13 * Class CRM_Event_BAO_ParticipantTest
f78dbf0b 14 *
acb109b7 15 * @group headless
4cbe18b8 16 */
6a488035 17class CRM_Event_BAO_ParticipantTest extends CiviUnitTestCase {
6a488035 18
00be9182 19 public function setUp() {
6a488035 20 parent::setUp();
6ae19242 21 $this->_contactId = $this->individualCreate();
22 $event = $this->eventCreate();
23 $this->_eventId = $event['id'];
6a488035
TO
24 }
25
26 /**
100fef9d 27 * Add() method (add and edit modes of participant)
6a488035 28 */
00be9182 29 public function testAdd() {
f78dbf0b 30 $params = [
6a488035
TO
31 'send_receipt' => 1,
32 'is_test' => 0,
33 'is_pay_later' => 0,
34 'event_id' => $this->_eventId,
35 'register_date' => date('Y-m-d') . " 00:00:00",
36 'role_id' => 1,
37 'status_id' => 1,
38 'source' => 'Event_' . $this->_eventId,
39 'contact_id' => $this->_contactId,
f78dbf0b 40 ];
6a488035
TO
41
42 // New Participant Created
43 $participant = CRM_Event_BAO_Participant::add($params);
44
45 $this->assertDBNotNull('CRM_Event_BAO_Participant', $this->_contactId, 'id',
46 'contact_id', 'Check DB for Participant of the contact'
47 );
48
49 $this->assertDBCompareValue('CRM_Event_BAO_Participant', $participant->id, 'contact_id',
50 'id', $this->_contactId, 'Check DB for contact of the participant'
51 );
52
f78dbf0b 53 $params = array_merge($params, [
92915c55
TO
54 'id' => $participant->id,
55 'role_id' => 2,
56 'status_id' => 3,
f78dbf0b 57 ]);
6a488035
TO
58
59 // Participant Edited
60 $updatedParticipant = CRM_Event_BAO_Participant::add($params);
61 $this->assertDBCompareValue('CRM_Event_BAO_Participant', $updatedParticipant->id, 'role_id',
62 'id', 2, 'Check DB for updated role id of the participant'
63 );
64
65 $this->assertDBCompareValue('CRM_Event_BAO_Participant', $updatedParticipant->id, 'status_id',
66 'id', 3, 'Check DB for updated status id of the participant'
67 );
68
93ac19cd 69 $this->contactDelete($this->_contactId);
6ae19242 70 $this->eventDelete($this->_eventId);
6a488035
TO
71 }
72
73 /**
100fef9d 74 * GetValues() method (fetch value of participant)
6a488035 75 */
00be9182 76 public function testgetValuesWithValidParams() {
f78dbf0b 77 $participantId = $this->participantCreate(['contact_id' => $this->_contactId, 'event_id' => $this->_eventId]);
78 $params = ['id' => $participantId];
79 $values = $ids = [];
6a488035
TO
80
81 $fetchParticipant = CRM_Event_BAO_Participant::getValues($params, $values, $ids);
82 $compareValues = $fetchParticipant[$participantId];
83
f78dbf0b 84 $params = [
6a488035
TO
85 'send_receipt' => 1,
86 'is_test' => 0,
87 'is_pay_later' => 0,
88 'event_id' => $this->_eventId,
6ae19242 89 'register_date' => '2007-02-19 00:00:00',
6a488035 90 'role_id' => 1,
6ae19242 91 'status_id' => 2,
92 'source' => 'Wimbeldon',
6a488035
TO
93 'contact_id' => $this->_contactId,
94 'id' => $participantId,
4b27d4ec 95 'campaign_id' => NULL,
6a488035
TO
96 'fee_level' => NULL,
97 'fee_amount' => NULL,
98 'registered_by_id' => NULL,
99 'discount_id' => NULL,
100 'fee_currency' => NULL,
4b27d4ec
E
101 'discount_amount' => NULL,
102 'cart_id' => NULL,
103 'must_wait' => NULL,
6ae19242 104 'transferred_to_contact_id' => NULL,
f78dbf0b 105 ];
6a488035
TO
106
107 foreach ($compareValues as $key => $value) {
108 if (substr($key, 0, 1) != '_' && $key != 'N') {
109 $this->assertEquals($compareValues->$key, $params[$key], 'Check for ' . $key . ' for given participant');
110 }
111 }
112
6ae19242 113 $this->participantDelete($participantId);
93ac19cd 114 $this->contactDelete($this->_contactId);
6ae19242 115 $this->eventDelete($this->_eventId);
6a488035
TO
116 }
117
118 /**
100fef9d 119 * GetValues() method (checking for behavior when params are empty )
6a488035 120 */
00be9182 121 public function testgetValuesWithoutValidParams() {
f78dbf0b 122 $params = $values = $ids = [];
123 $this->participantCreate(['contact_id' => $this->_contactId, 'event_id' => $this->_eventId]);
6a488035 124 $fetchParticipant = CRM_Event_BAO_Participant::getValues($params, $values, $ids);
a15773db 125 $this->assertNull($fetchParticipant);
6a488035 126
93ac19cd 127 $this->contactDelete($this->_contactId);
6ae19242 128 $this->eventDelete($this->_eventId);
6a488035
TO
129 }
130
131 /**
100fef9d 132 * EventFull() method (checking the event for full )
6a488035 133 */
00be9182 134 public function testEventFull() {
f78dbf0b 135 $eventParams = [
6a488035
TO
136 'max_participants' => 1,
137 'id' => $this->_eventId,
f78dbf0b 138 ];
6a488035
TO
139 CRM_Event_BAO_Event::add($eventParams);
140
f78dbf0b 141 $participantId = $this->participantCreate(['contact_id' => $this->_contactId, 'event_id' => $this->_eventId]);
6a488035
TO
142 $eventFull = CRM_Event_BAO_Participant::eventFull($this->_eventId);
143
6ae19242 144 $this->assertEquals($eventFull, 'Sorry! We are already full', 'Checking if Event is full.');
6a488035 145
6ae19242 146 $this->participantDelete($participantId);
93ac19cd 147 $this->contactDelete($this->_contactId);
6ae19242 148 $this->eventDelete($this->_eventId);
6a488035
TO
149 }
150
151 /**
100fef9d 152 * ImportableFields() method ( Checking the Event's Importable Fields )
6a488035 153 */
00be9182 154 public function testimportableFields() {
6a488035
TO
155 $importableFields = CRM_Event_BAO_Participant::importableFields();
156 $this->assertNotEquals(count($importableFields), 0, 'Checking array not to be empty.');
157
93ac19cd 158 $this->contactDelete($this->_contactId);
6ae19242 159 $this->eventDelete($this->_eventId);
6a488035
TO
160 }
161
162 /**
100fef9d 163 * ParticipantDetails() method ( Checking the Participant Details )
6a488035 164 */
00be9182 165 public function testparticipantDetails() {
f78dbf0b 166 $participant = $this->callAPISuccess('Participant', 'create', ['contact_id' => $this->_contactId, 'event_id' => $this->_eventId]);
167 $params = ['name' => 'Anderson, Anthony', 'title' => 'Annual CiviCRM meet'];
6a488035 168
6ae19242 169 $participantDetails = CRM_Event_BAO_Participant::participantDetails($participant['id']);
6a488035
TO
170
171 $this->assertEquals(count($participantDetails), 3, 'Equating the array contains.');
172 $this->assertEquals($participantDetails['name'], $params['name'], 'Checking Name of Participant.');
173 $this->assertEquals($participantDetails['title'], $params['title'], 'Checking Event Title in which participant is enroled.');
174
6ae19242 175 $this->participantDelete($participant['id']);
93ac19cd 176 $this->contactDelete($this->_contactId);
6ae19242 177 $this->eventDelete($this->_eventId);
6a488035
TO
178 }
179
180 /**
100fef9d 181 * DeleteParticipant() method ( Delete a Participant )
6a488035 182 */
00be9182 183 public function testdeleteParticipant() {
f78dbf0b 184 $params = [
6a488035
TO
185 'send_receipt' => 1,
186 'is_test' => 0,
187 'is_pay_later' => 0,
188 'event_id' => $this->_eventId,
189 'register_date' => date('Y-m-d') . " 00:00:00",
190 'role_id' => 1,
191 'status_id' => 1,
192 'source' => 'Event_' . $this->_eventId,
193 'contact_id' => $this->_contactId,
f78dbf0b 194 ];
6a488035
TO
195
196 // New Participant Created
197 $participant = CRM_Event_BAO_Participant::add($params);
198
199 $this->assertDBNotNull('CRM_Event_BAO_Participant', $this->_contactId, 'id',
200 'contact_id', 'Check DB for Participant of the contact'
201 );
202
203 $this->assertDBCompareValue('CRM_Event_BAO_Participant', $participant->id, 'contact_id',
204 'id', $this->_contactId, 'Check DB for contact of the participant'
205 );
206
93ac19cd 207 CRM_Event_BAO_Participant::deleteParticipant($participant->id);
6a488035
TO
208 $this->assertDBNull('CRM_Event_BAO_Participant', $participant->id, 'contact_id', 'id', 'Check DB for deleted Participant.');
209
93ac19cd 210 $this->contactDelete($this->_contactId);
6ae19242 211 $this->eventDelete($this->_eventId);
6a488035
TO
212 }
213
214 /**
100fef9d 215 * CheckDuplicate() method ( Checking for Duplicate Participant returns array of participant id)
6a488035 216 */
00be9182 217 public function testcheckDuplicate() {
f78dbf0b 218 $duplicate = [];
6a488035
TO
219
220 //Creating 3 new participants
221 for ($i = 0; $i < 3; $i++) {
f78dbf0b 222 $partiId[] = $this->participantCreate(['contact_id' => $this->_contactId, 'event_id' => $this->_eventId]);
6a488035
TO
223 }
224
f78dbf0b 225 $params = ['event_id' => $this->_eventId, 'contact_id' => $this->_contactId];
6ae19242 226 CRM_Event_BAO_Participant::checkDuplicate($params, $duplicate);
6a488035
TO
227
228 $this->assertEquals(count($duplicate), 3, 'Equating the array contains with duplicate array.');
229
230 //Checking for the duplicate participant
231 foreach ($duplicate as $key => $value) {
232 $this->assertEquals($partiId[$key], $duplicate[$key], 'Equating the contactid which is in the database.');
233 }
234
235 //Deleting all participant
236 for ($i = 0; $i < 3; $i++) {
6ae19242 237 $partidel[] = $this->participantDelete($partiId[$i]);
6a488035
TO
238 }
239
93ac19cd 240 $this->contactDelete($this->_contactId);
6ae19242 241 $this->eventDelete($this->_eventId);
6a488035
TO
242 }
243
244 /**
100fef9d 245 * Create() method (create and updation of participant)
6a488035 246 */
00be9182 247 public function testCreate() {
f78dbf0b 248 $params = [
6a488035
TO
249 'send_receipt' => 1,
250 'is_test' => 0,
251 'is_pay_later' => 0,
252 'event_id' => $this->_eventId,
253 'register_date' => date('Y-m-d') . " 00:00:00",
254 'role_id' => 1,
255 'status_id' => 1,
256 'source' => 'Event_' . $this->_eventId,
257 'contact_id' => $this->_contactId,
258 'note' => 'Note added for Event_' . $this->_eventId,
f78dbf0b 259 ];
6a488035
TO
260
261 $participant = CRM_Event_BAO_Participant::create($params);
262 //Checking for Contact id in the participant table.
263 $pid = $this->assertDBNotNull('CRM_Event_DAO_Participant', $this->_contactId, 'id',
264 'contact_id', 'Check DB for Participant of the contact'
265 );
266
267 //Checking for Activity added in the table for relative participant.
268 $this->assertDBCompareValue('CRM_Activity_DAO_Activity', $this->_contactId, 'source_record_id',
269 'source_contact_id', $participant->id, 'Check DB for activity added for the participant'
270 );
271
f78dbf0b 272 $params = array_merge($params, [
6a488035 273 'id' => $participant->id,
92915c55
TO
274 'role_id' => 2,
275 'status_id' => 3,
276 'note' => 'Test Event in edit mode is running successfully ....',
f78dbf0b 277 ]);
6a488035
TO
278
279 $participant = CRM_Event_BAO_Participant::create($params);
280
281 //Checking Edited Value of role_id in the database.
282 $this->assertDBCompareValue('CRM_Event_DAO_Participant', $participant->id, 'role_id',
283 'id', 2, 'Check DB for updated role id of the participant'
284 );
285
286 //Checking Edited Value of status_id in the database.
287 $this->assertDBCompareValue('CRM_Event_DAO_Participant', $participant->id, 'status_id',
288 'id', 3, 'Check DB for updated status id of the participant'
289 );
290
291 //Checking for Activity added in the table for relative participant.
292 $this->assertDBCompareValue('CRM_Activity_DAO_Activity', $this->_contactId, 'source_record_id',
293 'source_contact_id', $participant->id, 'Check DB for activity added for the participant'
294 );
295
296 //Checking for Note added in the table for relative participant.
297 $session = CRM_Core_Session::singleton();
298 $id = $session->get('userID');
299 if (!$id) {
300 $id = $this->_contactId;
301 }
302
303 //Deleting the Participant created by create function in this function
23ead872 304 CRM_Event_BAO_Participant::deleteParticipant($participant->id);
6a488035
TO
305 $this->assertDBNull('CRM_Event_DAO_Participant', $this->_contactId, 'id',
306 'contact_id', 'Check DB for deleted participant. Should be NULL.'
307 );
308
93ac19cd 309 $this->contactDelete($this->_contactId);
6ae19242 310 $this->eventDelete($this->_eventId);
6a488035
TO
311 }
312
313 /**
100fef9d 314 * ExportableFields() method ( Exportable Fields for Participant)
6a488035 315 */
00be9182 316 public function testexportableFields() {
6a488035
TO
317 $exportableFields = CRM_Event_BAO_Participant::exportableFields();
318 $this->assertNotEquals(count($exportableFields), 0, 'Checking array not to be empty.');
319
93ac19cd 320 $this->contactDelete($this->_contactId);
6ae19242 321 $this->eventDelete($this->_eventId);
6a488035
TO
322 }
323
324 /**
100fef9d 325 * FixEventLevel() method (Setting ',' values), resolveDefaults(assinging value to array) method
6a488035 326 */
00be9182 327 public function testfixEventLevel() {
6a488035
TO
328
329 $paramsSet['title'] = 'Price Set';
330 $paramsSet['name'] = CRM_Utils_String::titleToVar('Price Set');
4b27d4ec 331 $paramsSet['is_active'] = FALSE;
6a488035
TO
332 $paramsSet['extends'] = 1;
333
9da8dc8c 334 $priceset = CRM_Price_BAO_PriceSet::create($paramsSet);
6a488035
TO
335
336 //Checking for priceset added in the table.
9da8dc8c 337 $this->assertDBCompareValue('CRM_Price_BAO_PriceSet', $priceset->id, 'title',
6a488035
TO
338 'id', $paramsSet['title'], 'Check DB for created priceset'
339 );
f78dbf0b 340 $paramsField = [
6a488035
TO
341 'label' => 'Price Field',
342 'name' => CRM_Utils_String::titleToVar('Price Field'),
343 'html_type' => 'Text',
344 'price' => 10,
f78dbf0b 345 'option_label' => ['1' => 'Price Field'],
346 'option_value' => ['1' => 10],
347 'option_name' => ['1' => 10],
348 'option_weight' => ['1' => 1],
6a488035
TO
349 'is_display_amounts' => 1,
350 'weight' => 1,
351 'options_per_line' => 1,
f78dbf0b 352 'is_active' => ['1' => 1],
6a488035
TO
353 'price_set_id' => $priceset->id,
354 'is_enter_qty' => 1,
f78dbf0b 355 ];
6a488035 356
f78dbf0b 357 $ids = [];
9da8dc8c 358 $pricefield = CRM_Price_BAO_PriceField::create($paramsField, $ids);
6a488035
TO
359
360 //Checking for priceset added in the table.
9da8dc8c 361 $this->assertDBCompareValue('CRM_Price_BAO_PriceField', $pricefield->id, 'label',
6a488035
TO
362 'id', $paramsField['label'], 'Check DB for created pricefield'
363 );
364
365 $eventId = $this->_eventId;
f78dbf0b 366 $participantParams = [
6a488035
TO
367 'send_receipt' => 1,
368 'is_test' => 0,
369 'is_pay_later' => 0,
370 'event_id' => $eventId,
371 'register_date' => date('Y-m-d') . " 00:00:00",
372 'role_id' => 1,
373 'status_id' => 1,
374 'source' => 'Event_' . $eventId,
375 'contact_id' => $this->_contactId,
376 'note' => 'Note added for Event_' . $eventId,
377 'fee_level' => '\ 1Price_Field - 55\ 1',
f78dbf0b 378 ];
6a488035
TO
379
380 $participant = CRM_Event_BAO_Participant::add($participantParams);
381
382 //Checking for participant added in the table.
383 $this->assertDBCompareValue('CRM_Event_BAO_Participant', $this->_contactId, 'id',
384 'contact_id', $participant->id, 'Check DB for created participant'
385 );
386
f78dbf0b 387 $values = [];
388 $ids = [];
389 $params = ['id' => $participant->id];
6a488035
TO
390
391 CRM_Event_BAO_Participant::getValues($params, $values, $ids);
392 $this->assertNotEquals(count($values), 0, 'Checking for empty array.');
393
394 CRM_Event_BAO_Participant::resolveDefaults($values[$participant->id]);
395
396 if ($values[$participant->id]['fee_level']) {
397 CRM_Event_BAO_Participant::fixEventLevel($values[$participant->id]['fee_level']);
398 }
399
93ac19cd 400 CRM_Price_BAO_PriceField::deleteField($pricefield->id);
9da8dc8c 401 $this->assertDBNull('CRM_Price_BAO_PriceField', $pricefield->id, 'name',
6a488035
TO
402 'id', 'Check DB for non-existence of Price Field.'
403 );
404
93ac19cd 405 CRM_Price_BAO_PriceSet::deleteSet($priceset->id);
9da8dc8c 406 $this->assertDBNull('CRM_Price_BAO_PriceSet', $priceset->id, 'title',
6a488035
TO
407 'id', 'Check DB for non-existence of Price Set.'
408 );
409
6ae19242 410 $this->participantDelete($participant->id);
93ac19cd 411 $this->contactDelete($this->_contactId);
6ae19242 412 $this->eventDelete($eventId);
6a488035 413 }
96025800 414
4a3451de
JG
415 /**
416 * Test various self-service eligibility scenarios.
417 *
418 * @dataProvider selfServiceScenarios
419 * @param $selfSvcEnabled
420 * @param $selfSvcHours
421 * @param $hoursToEvent
422 * @param $participantStatusId
423 * @param $isBackOffice
424 * @param $successExpected A boolean that indicates whether this test should pass or fail.
425 */
426 public function testGetSelfServiceEligibility($selfSvcEnabled, $selfSvcHours, $hoursToEvent, $participantStatusId, $isBackOffice, $successExpected) {
427 $participantId = $this->participantCreate(['contact_id' => $this->_contactId, 'event_id' => $this->_eventId, 'status_id' => $participantStatusId]);
428 $now = new Datetime();
429 $startDate = $now->add(new DateInterval("PT{$hoursToEvent}H"))->format('Y-m-d H:i:s');
430 $this->callAPISuccess('Event', 'create', [
431 'id' => $this->_eventId,
432 'allow_selfcancelxfer' => $selfSvcEnabled,
433 'selfcancelxfer_time' => $selfSvcHours,
434 'start_date' => $startDate,
435 ]);
436 $url = CRM_Utils_System::url('civicrm/event/info', "reset=1&id={$this->_eventId}");
c0fc0432
JG
437 $details = CRM_Event_BAO_Participant::getSelfServiceEligibility($participantId, $url, $isBackOffice);
438 $this->assertEquals($details['eligible'], $successExpected);
4a3451de
JG
439 }
440
441 public function selfServiceScenarios() {
442 // Standard pass scenario
443 $scenarios[] = [
c0fc0432 444 'selfSvcEnabled' => 1,
4a3451de
JG
445 'selfSvcHours' => 12,
446 'hoursToEvent' => 16,
447 'participantStatusId' => 1,
448 'isBackOffice' => FALSE,
449 'successExpected' => TRUE,
450 ];
451 // Too late to self-service
452 $scenarios[] = [
c0fc0432 453 'selfSvcEnabled' => 1,
4a3451de
JG
454 'selfSvcHours' => 12,
455 'hoursToEvent' => 8,
456 'participantStatusId' => 1,
457 'isBackOffice' => FALSE,
458 'successExpected' => FALSE,
459 ];
460 // Participant status is other than "Registered".
461 $scenarios[] = [
c0fc0432 462 'selfSvcEnabled' => 1,
4a3451de
JG
463 'selfSvcHours' => 12,
464 'hoursToEvent' => 16,
465 'participantStatusId' => 2,
466 'isBackOffice' => FALSE,
467 'successExpected' => FALSE,
468 ];
c0fc0432
JG
469 // Event doesn't allow self-service
470 $scenarios[] = [
471 'selfSvcEnabled' => 0,
472 'selfSvcHours' => 12,
473 'hoursToEvent' => 16,
474 'participantStatusId' => 1,
475 'isBackOffice' => FALSE,
476 'successExpected' => FALSE,
477 ];
478 // Cancellation deadline is > 24 hours, still ok to cancel
479 $scenarios[] = [
480 'selfSvcEnabled' => 1,
481 'selfSvcHours' => 36,
482 'hoursToEvent' => 46,
483 'participantStatusId' => 1,
484 'isBackOffice' => FALSE,
485 'successExpected' => TRUE,
486 ];
487 // Cancellation deadline is > 24 hours, too late to cancel
488 $scenarios[] = [
489 'selfSvcEnabled' => 1,
490 'selfSvcHours' => 36,
491 'hoursToEvent' => 25,
492 'participantStatusId' => 1,
493 'isBackOffice' => FALSE,
494 'successExpected' => FALSE,
495 ];
4a3451de
JG
496 return $scenarios;
497 }
498
6a488035 499}