Merge pull request #15529 from civicrm/5.19
[civicrm-core.git] / tests / phpunit / CRM / Event / Form / Registration / ConfirmTest.php
1 <?php
2
3 /**
4 * Test CRM_Event_Form_Registration functions.
5 *
6 * @package CiviCRM
7 * @group headless
8 */
9 class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase {
10
11 use CRMTraits_Profile_ProfileTrait;
12
13 public function setUp() {
14 $this->useTransaction(TRUE);
15 parent::setUp();
16 }
17
18 /**
19 * Initial test of submit function.
20 *
21 * @throws \Exception
22 */
23 public function testSubmit() {
24 $event = $this->eventCreate();
25 $mut = new CiviMailUtils($this, TRUE);
26 CRM_Event_Form_Registration_Confirm::testSubmit([
27 'id' => $event['id'],
28 'contributeMode' => 'direct',
29 'registerByID' => $this->createLoggedInUser(),
30 'params' => [
31 [
32 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
33 'entryURL' => 'http://dmaster.local/civicrm/event/register?reset=1&amp;id=3',
34 'first_name' => 'k',
35 'last_name' => 'p',
36 'email-Primary' => 'demo@example.com',
37 'hidden_processor' => '1',
38 'credit_card_number' => '4111111111111111',
39 'cvv2' => '123',
40 'credit_card_exp_date' => [
41 'M' => '1',
42 'Y' => '2019',
43 ],
44 'credit_card_type' => 'Visa',
45 'billing_first_name' => 'p',
46 'billing_middle_name' => '',
47 'billing_last_name' => 'p',
48 'billing_street_address-5' => 'p',
49 'billing_city-5' => 'p',
50 'billing_state_province_id-5' => '1061',
51 'billing_postal_code-5' => '7',
52 'billing_country_id-5' => '1228',
53 'scriptFee' => '',
54 'scriptArray' => '',
55 'priceSetId' => '6',
56 'price_7' => [
57 13 => 1,
58 ],
59 'payment_processor_id' => '1',
60 'bypass_payment' => '',
61 'MAX_FILE_SIZE' => '33554432',
62 'is_primary' => 1,
63 'is_pay_later' => 0,
64 'campaign_id' => NULL,
65 'defaultRole' => 1,
66 'participant_role_id' => '1',
67 'currencyID' => 'USD',
68 'amount_level' => '\ 1Tiny-tots (ages 5-8) - 1\ 1',
69 'amount' => '800.00',
70 'tax_amount' => NULL,
71 'year' => '2019',
72 'month' => '1',
73 'ip_address' => '127.0.0.1',
74 'invoiceID' => '57adc34957a29171948e8643ce906332',
75 'button' => '_qf_Register_upload',
76 'billing_state_province-5' => 'AP',
77 'billing_country-5' => 'US',
78 ],
79 ],
80 ]);
81 $participant = $this->callAPISuccessGetSingle('Participant', []);
82 $mut->checkMailLog([
83 'Dear Logged In, Thank you for your participation. This letter is a confirmation that your registration has been received and your status has been updated to Registered.',
84 ]);
85 $mut->stop();
86 $mut->clearMessages();
87 $tplVars = CRM_Core_Smarty::singleton()->get_template_vars();
88 $this->assertEquals($participant['id'], $tplVars['participantID']);
89
90 }
91
92 /**
93 * Initial test of submit function for paid event.
94 *
95 * @param string $thousandSeparator
96 *
97 * @dataProvider getThousandSeparators
98 *
99 * @throws \Exception
100 */
101 public function testPaidSubmit($thousandSeparator) {
102 $this->setCurrencySeparators($thousandSeparator);
103 $paymentProcessorID = $this->processorCreate();
104 /* @var \CRM_Core_Payment_Dummy $processor */
105 $processor = Civi\Payment\System::singleton()->getById($paymentProcessorID);
106 $processor->setDoDirectPaymentResult(['fee_amount' => 1.67]);
107 $params = ['is_monetary' => 1, 'financial_type_id' => 1];
108 $event = $this->eventCreate($params);
109 $individualID = $this->individualCreate();
110 CRM_Event_Form_Registration_Confirm::testSubmit([
111 'id' => $event['id'],
112 'contributeMode' => 'direct',
113 'registerByID' => $individualID,
114 'paymentProcessorObj' => CRM_Financial_BAO_PaymentProcessor::getPayment($paymentProcessorID),
115 'totalAmount' => $this->formatMoneyInput(8000.67),
116 'params' => [
117 [
118 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
119 'entryURL' => 'http://dmaster.local/civicrm/event/register?reset=1&amp;id=3',
120 'first_name' => 'k',
121 'last_name' => 'p',
122 'email-Primary' => 'demo@example.com',
123 'hidden_processor' => '1',
124 'credit_card_number' => '4111111111111111',
125 'cvv2' => '123',
126 'credit_card_exp_date' => [
127 'M' => '1',
128 'Y' => '2019',
129 ],
130 'credit_card_type' => 'Visa',
131 'billing_first_name' => 'p',
132 'billing_middle_name' => '',
133 'billing_last_name' => 'p',
134 'billing_street_address-5' => 'p',
135 'billing_city-5' => 'p',
136 'billing_state_province_id-5' => '1061',
137 'billing_postal_code-5' => '7',
138 'billing_country_id-5' => '1228',
139 'scriptFee' => '',
140 'scriptArray' => '',
141 'priceSetId' => '6',
142 'price_7' => [
143 13 => 1,
144 ],
145 'payment_processor_id' => $paymentProcessorID,
146 'bypass_payment' => '',
147 'MAX_FILE_SIZE' => '33554432',
148 'is_primary' => 1,
149 'is_pay_later' => 0,
150 'campaign_id' => NULL,
151 'defaultRole' => 1,
152 'participant_role_id' => '1',
153 'currencyID' => 'USD',
154 'amount_level' => '\ 1Tiny-tots (ages 5-8) - 1\ 1',
155 'amount' => $this->formatMoneyInput(8000.67),
156 'tax_amount' => NULL,
157 'year' => '2019',
158 'month' => '1',
159 'ip_address' => '127.0.0.1',
160 'invoiceID' => '57adc34957a29171948e8643ce906332',
161 'button' => '_qf_Register_upload',
162 'billing_state_province-5' => 'AP',
163 'billing_country-5' => 'US',
164 ],
165 ],
166 ]);
167 $this->callAPISuccessGetCount('Participant', [], 1);
168 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
169 $this->assertEquals(8000.67, $contribution['total_amount']);
170 $this->assertEquals(1.67, $contribution['fee_amount']);
171 $this->assertEquals(7999, $contribution['net_amount']);
172 $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
173 $financialTrxn = $this->callAPISuccessGetSingle(
174 'FinancialTrxn',
175 [
176 'id' => $lastFinancialTrxnId['financialTrxnId'],
177 'return' => ['payment_processor_id', 'card_type_id.label', 'pan_truncation'],
178 ]
179 );
180 $this->assertEquals(CRM_Utils_Array::value('payment_processor_id', $financialTrxn), $paymentProcessorID);
181 $this->assertEquals(CRM_Utils_Array::value('card_type_id.label', $financialTrxn), 'Visa');
182 $this->assertEquals(CRM_Utils_Array::value('pan_truncation', $financialTrxn), 1111);
183
184 // This looks like it's missing an item for the main contribution - but just locking in current behaviour.
185 $financialItems = $this->callAPISuccess('FinancialItem', 'get', [
186 'return' => ['description', 'financial_account_id', 'amount', 'contact_id', 'currency', 'status_id', 'entity_table', 'entity_id'],
187 'sequential' => 1,
188 ])['values'];
189
190 $entityFinancialTrxns = $this->callAPISuccess('EntityFinancialTrxn', 'get', ['sequential' => 1])['values'];
191
192 $this->assertAPIArrayComparison([
193 'entity_table' => 'civicrm_contribution',
194 'entity_id' => $contribution['id'],
195 'financial_trxn_id' => $financialTrxn['id'],
196 'amount' => '8000.67',
197 ], $entityFinancialTrxns[0], ['id']);
198
199 $this->assertAPIArrayComparison([
200 'entity_table' => 'civicrm_contribution',
201 'entity_id' => $contribution['id'],
202 'financial_trxn_id' => $financialTrxn['id'] + 1,
203 'amount' => '1.67',
204 ], $entityFinancialTrxns[1], ['id']);
205
206 $this->assertAPIArrayComparison([
207 'entity_table' => 'civicrm_financial_item',
208 'entity_id' => $financialItems[0]['id'],
209 'financial_trxn_id' => $financialTrxn['id'] + 1,
210 'amount' => '1.67',
211 ], $entityFinancialTrxns[2], ['id', 'entity_id']);
212 }
213
214 /**
215 * Test for Tax amount for multiple participant.
216 *
217 * @throws \CRM_Core_Exception
218 */
219 public function testTaxMultipleParticipant() {
220 $mut = new CiviMailUtils($this);
221 $params = ['is_monetary' => 1, 'financial_type_id' => 1];
222 $event = $this->eventCreate($params);
223 CRM_Event_Form_Registration_Confirm::testSubmit([
224 'id' => $event['id'],
225 'contributeMode' => 'direct',
226 'registerByID' => $this->createLoggedInUser(),
227 'totalAmount' => 440,
228 'event' => reset($event['values']),
229 'params' => [
230 [
231 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
232 'entryURL' => "http://dmaster.local/civicrm/event/register?reset=1&amp;id={$event['id']}",
233 'first_name' => 'Participant1',
234 'last_name' => 'LastName',
235 'email-Primary' => 'participant1@example.com',
236 'additional_participants' => 2,
237 'payment_processor_id' => 0,
238 'bypass_payment' => '',
239 'MAX_FILE_SIZE' => '33554432',
240 'is_primary' => 1,
241 'is_pay_later' => 1,
242 'campaign_id' => NULL,
243 'defaultRole' => 1,
244 'participant_role_id' => '1',
245 'currencyID' => 'USD',
246 'amount_level' => '\ 1Tiny-tots (ages 5-8) - 1\ 1',
247 'amount' => '100.00',
248 'tax_amount' => 10,
249 'ip_address' => '127.0.0.1',
250 'invoiceID' => '57adc34957a29171948e8643ce906332',
251 'trxn_id' => '123456789',
252 'button' => '_qf_Register_upload',
253 ],
254 [
255 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
256 'entryURL' => "http://dmaster.local/civicrm/event/register?reset=1&amp;id={$event['id']}",
257 'first_name' => 'Participant2',
258 'last_name' => 'LastName',
259 'email-Primary' => 'participant2@example.com',
260 'scriptFee' => '',
261 'scriptArray' => '',
262 'campaign_id' => NULL,
263 'is_pay_later' => 1,
264 'participant_role_id' => '1',
265 'currencyID' => 'USD',
266 'amount_level' => '\ 1Tiny-tots (ages 9-18) - 1\ 1',
267 'amount' => '200.00',
268 'tax_amount' => 20,
269 ],
270 [
271 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
272 'entryURL' => "http://dmaster.local/civicrm/event/register?reset=1&amp;id={$event['id']}",
273 'first_name' => 'Participant3',
274 'last_name' => 'LastName',
275 'email-Primary' => 'participant3@example.com',
276 'scriptFee' => '',
277 'scriptArray' => '',
278 'campaign_id' => NULL,
279 'is_pay_later' => 1,
280 'participant_role_id' => '1',
281 'currencyID' => 'USD',
282 'amount_level' => '\ 1Tiny-tots (ages 5-8) - 1\ 1',
283 'amount' => '100.00',
284 'tax_amount' => 10,
285 ],
286 ],
287 ]);
288 $participants = $this->callAPISuccess('Participant', 'get', [])['values'];
289 $this->assertCount(3, $participants);
290 $contribution = $this->callAPISuccessGetSingle(
291 'Contribution',
292 [
293 'return' => ['tax_amount', 'total_amount'],
294 ]
295 );
296 $this->assertEquals($contribution['tax_amount'], 40, 'Invalid Tax amount.');
297 $this->assertEquals($contribution['total_amount'], 440, 'Invalid Tax amount.');
298 $mailSent = $mut->getAllMessages();
299 $this->assertCount(3, $mailSent, 'Three mails should have been sent to the 3 participants.');
300 }
301
302 /**
303 * Test online registration for event with no price options selected as per CRM-19964.
304 */
305 public function testOnlineRegNoPrice() {
306 $paymentProcessorID = $this->processorCreate(['is_default' => TRUE, 'user_name' => 'Test', 'is_test' => FALSE]);
307 $paymentProcessorID = $this->processorCreate(['is_default' => TRUE, 'user_name' => 'Test', 'is_test' => TRUE]);
308 $params = [
309 'start_date' => date('YmdHis', strtotime('+ 1 week')),
310 'end_date' => date('YmdHis', strtotime('+ 1 year')),
311 'registration_start_date' => date('YmdHis', strtotime('- 1 day')),
312 'registration_end_date' => date('YmdHis', strtotime('+ 1 year')),
313 'payment_processor_id' => $paymentProcessorID,
314 'is_monetary' => TRUE,
315 'financial_type_id' => 'Event Fee',
316 ];
317 $event = $this->eventCreate($params);
318 $priceFieldOptions = [
319 'option_label' => 'Price Field',
320 'option_value' => 100,
321 'is_required' => FALSE,
322 'html_type' => 'Text',
323 ];
324 $this->createPriceSet('event', $event['id'], $priceFieldOptions);
325
326 $priceField = $this->callAPISuccess('PriceField', 'get',
327 [
328 'label' => 'Price Field',
329 ]
330 );
331 // Create online event registration.
332 CRM_Event_Form_Registration_Confirm::testSubmit([
333 'id' => $event['id'],
334 'contributeMode' => 'direct',
335 'registerByID' => $this->createLoggedInUser(),
336 'params' => [
337 [
338 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
339 'entryURL' => "http://dmaster.local/civicrm/event/register?reset=1&amp;id={$event['id']}",
340 'first_name' => 'Bruce',
341 'last_name' => 'Wayne',
342 'email-Primary' => 'bruce@gotham.com',
343 'price_' . $priceField['id'] => '',
344 'priceSetId' => $priceField['values'][$priceField['id']]['price_set_id'],
345 'payment_processor_id' => $paymentProcessorID,
346 'amount' => 0,
347 'bypass_payment' => '',
348 'MAX_FILE_SIZE' => '33554432',
349 'is_primary' => 1,
350 'is_pay_later' => 0,
351 'campaign_id' => NULL,
352 'defaultRole' => 1,
353 'participant_role_id' => '1',
354 'tax_amount' => NULL,
355 'ip_address' => '127.0.0.1',
356 'invoiceID' => '57adc34957a29171948e8643ce906332',
357 'button' => '_qf_Register_upload',
358 'scriptFee' => '',
359 'scriptArray' => '',
360 ],
361 ],
362 ]);
363 $contribution = $this->callAPISuccess('Contribution', 'get', ['invoice_id' => '57adc34957a29171948e8643ce906332']);
364 $this->assertEquals($contribution['count'], '0', "Contribution should not be created for zero fee event registration when no price field selected.");
365 }
366
367 /**
368 * Test form profile assignment.
369 *
370 * @throws \CRM_Core_Exception
371 * @throws \Exception
372 */
373 public function testAssignProfiles() {
374 $event = $this->eventCreate();
375 $this->createJoinedProfile(['entity_table' => 'civicrm_event', 'entity_id' => $event['id']]);
376
377 /* @var \CRM_Event_Form_Registration_Confirm $form */
378 $form = $this->getFormObject('CRM_Event_Form_Registration_Confirm');
379 $form->set('params', [[]]);
380 $form->set('id', $event['id']);
381 $form->set('values', [
382 'event' => $event['values'][$event['id']],
383 'location' => [],
384 'custom_pre_id' => $this->ids['UFGroup']['our profile'],
385 ]);
386 $form->preProcess();
387
388 CRM_Event_Form_Registration_Confirm::assignProfiles($form);
389
390 $smarty = CRM_Core_Smarty::singleton();
391 $tplVar = $smarty->get_template_vars();
392 $this->assertEquals([
393 'CustomPre' => ['First Name' => NULL],
394 'CustomPreGroupTitle' => 'Public title',
395 ], $tplVar['primaryParticipantProfile']);
396 }
397
398 /**
399 * Submit event registration with a note field
400 *
401 * @param array $event
402 * @param int $contact_id
403 *
404 * @throws \Exception
405 */
406 private function submitWithNote($event, $contact_id) {
407 if (empty($contact_id)) {
408 $contact_id = $this->createLoggedInUser();
409 }
410 $mut = new CiviMailUtils($this, TRUE);
411 CRM_Event_Form_Registration_Confirm::testSubmit([
412 'id' => $event['id'],
413 'contributeMode' => 'direct',
414 'registerByID' => $contact_id,
415 'custom_pre_id' => $event['custom_pre_id'],
416 'params' => [
417 [
418 'qfKey' => 'e6eb2903eae63d4c5c6cc70bfdda8741_2801',
419 'entryURL' => 'http://dmaster.local/civicrm/event/register?reset=1&amp;id=3',
420 'first_name' => 'k',
421 'last_name' => 'p',
422 'email-Primary' => 'demo@example.com',
423 'hidden_processor' => '1',
424 'credit_card_number' => '4111111111111111',
425 'cvv2' => '123',
426 'credit_card_exp_date' => [
427 'M' => '1',
428 'Y' => '2019',
429 ],
430 'credit_card_type' => 'Visa',
431 'billing_first_name' => 'p',
432 'billing_middle_name' => '',
433 'billing_last_name' => 'p',
434 'billing_street_address-5' => 'p',
435 'billing_city-5' => 'p',
436 'billing_state_province_id-5' => '1061',
437 'billing_postal_code-5' => '7',
438 'billing_country_id-5' => '1228',
439 'scriptFee' => '',
440 'scriptArray' => '',
441 'priceSetId' => '6',
442 'price_7' => [
443 13 => 1,
444 ],
445 'payment_processor_id' => '1',
446 'bypass_payment' => '',
447 'MAX_FILE_SIZE' => '33554432',
448 'is_primary' => 1,
449 'is_pay_later' => 0,
450 'campaign_id' => NULL,
451 'defaultRole' => 1,
452 'participant_role_id' => '1',
453 'currencyID' => 'USD',
454 'amount_level' => '\ 1Tiny-tots (ages 5-8) - 1\ 1',
455 'amount' => '800.00',
456 'tax_amount' => NULL,
457 'year' => '2019',
458 'month' => '1',
459 'ip_address' => '127.0.0.1',
460 'invoiceID' => '57adc34957a29171948e8643ce906332',
461 'button' => '_qf_Register_upload',
462 'billing_state_province-5' => 'AP',
463 'billing_country-5' => 'US',
464 'note' => $event['note'],
465 ],
466 ],
467 ]);
468 $participant = $this->callAPISuccessGetSingle('Participant', []);
469 $mut->checkMailLog(['Comment: ' . $event['note'] . chr(0x0A)]);
470 $mut->stop();
471 $mut->clearMessages();
472 $tplVars = CRM_Core_Smarty::singleton()->get_template_vars();
473 $this->assertEquals($participant['id'], $tplVars['participantID']);
474 //return ['contact_id' => $contact_id, 'participant_id' => $participant['id']];
475 return [$contact_id, $participant['id']];
476 }
477
478 /**
479 * Create an event with a "pre" profile
480 *
481 * @throws \CRM_Core_Exception
482 * @throws \Exception
483 */
484 private function creatEventWithProfile($event) {
485 if (empty($event)) {
486 $event = $this->eventCreate();
487 $this->createJoinedProfile(['entity_table' => 'civicrm_event', 'entity_id' => $event['id']]);
488 $this->uf_field_add($this->ids["UFGroup"]["our profile"], 'note', 'Contact', 'Comment');
489 }
490
491 /* @var \CRM_Event_Form_Registration_Confirm $form */
492 $form = $this->getFormObject('CRM_Event_Form_Registration_Confirm');
493 $form->set('params', [[]]);
494 $form->set('id', $event['id']);
495 $form->set('values', [
496 'event' => $event['values'][$event['id']],
497 'location' => [],
498 'custom_pre_id' => $this->ids['UFGroup']['our profile'],
499 ]);
500 $form->preProcess();
501
502 CRM_Event_Form_Registration_Confirm::assignProfiles($form);
503
504 $smarty = CRM_Core_Smarty::singleton();
505 $tplVar = $smarty->get_template_vars();
506 $this->assertEquals([
507 'CustomPre' => ['First Name' => NULL, 'Comment' => NULL],
508 'CustomPreGroupTitle' => 'Public title',
509 ], $tplVar['primaryParticipantProfile']);
510 return $event;
511 }
512
513 /**
514 * Add a field to the specified profile
515 *
516 * @param int $uf_group_id
517 * @param string $field_name
518 * @param string $field_type
519 * @param string $field_label
520 * @return array
521 * API result array
522 */
523 private function uf_field_add($uf_group_id, $field_name, $field_type, $field_label) {
524 $params = [
525 'field_name' => $field_name,
526 'field_type' => $field_type,
527 'visibility' => 'Public Pages and Listings',
528 'weight' => 1,
529 'label' => $field_label,
530 'is_searchable' => 1,
531 'is_active' => 1,
532 'uf_group_id' => $uf_group_id,
533 ];
534 $result = civicrm_api3('UFField', 'create', $params);
535 return $result;
536 }
537
538 /**
539 * /dev/event#10
540 * Test submission with a note in the profile, ensuring the confirmation
541 * email reflects the submitted value
542 */
543 public function testNoteSubmission() {
544 //create an event with an attached profile containing a note
545 $event = $this->creatEventWithProfile(NULL);
546 $event['custom_pre_id'] = $this->ids["UFGroup"]["our profile"];
547 $event['note'] = "This is note 1";
548 list($contact_id, $participant_id) = $this->submitWithNote($event, NULL);
549 civicrm_api3('Participant', 'delete', ['id' => $participant_id]);
550
551 //now that the contact has one note, register this contact again with a different note
552 //and confirm that the note shown in the email is the current one
553 $event = $this->creatEventWithProfile($event);
554 $event['custom_pre_id'] = $this->ids["UFGroup"]["our profile"];
555 $event['note'] = "This is note 2";
556 list($contact_id, $participant_id) = $this->submitWithNote($event, $contact_id);
557 civicrm_api3('Participant', 'delete', ['id' => $participant_id]);
558
559 //finally, submit a blank note and confirm that the note shown in the email is blank
560 $event = $this->creatEventWithProfile($event);
561 $event['custom_pre_id'] = $this->ids["UFGroup"]["our profile"];
562 $event['note'] = "";
563 list($contact_id, $participant_id) = $this->submitWithNote($event, $contact_id);
564 }
565
566 }