Further test improvement
[civicrm-core.git] / tests / phpunit / CRM / Contribute / Form / ContributionTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
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 /**
29 * Test APIv3 civicrm_contribute_* functions
30 *
31 * @package CiviCRM_APIv3
32 * @subpackage API_Contribution
33 * @group headless
34 */
35 class CRM_Contribute_Form_ContributionTest extends CiviUnitTestCase {
36
37 /**
38 * Assume empty database with just civicrm_data.
39 */
40 protected $_individualId;
41 protected $_contribution;
42 protected $_financialTypeId = 1;
43 protected $_apiversion;
44 protected $_entity = 'Contribution';
45 protected $_params;
46 protected $_ids = array();
47 protected $_pageParams = array();
48
49 /**
50 * Parameters to create payment processor.
51 *
52 * @var array
53 */
54 protected $_processorParams = array();
55
56 /**
57 * ID of created event.
58 *
59 * @var int
60 */
61 protected $_eventID;
62
63 /**
64 * Payment instrument mapping.
65 *
66 * @var array
67 */
68 protected $paymentInstruments = array();
69
70 /**
71 * Products.
72 *
73 * @var array
74 */
75 protected $products = array();
76
77 /**
78 * Dummy payment processor.
79 *
80 * @var CRM_Core_Payment_Dummy
81 */
82 protected $paymentProcessor;
83
84 /**
85 * Payment processor ID.
86 *
87 * @var int
88 */
89 protected $paymentProcessorID;
90
91 /**
92 * Setup function.
93 */
94 public function setUp() {
95 $this->_apiversion = 3;
96 parent::setUp();
97 $this->createLoggedInUser();
98
99 $this->_individualId = $this->individualCreate();
100 $this->_params = array(
101 'contact_id' => $this->_individualId,
102 'receive_date' => '20120511',
103 'total_amount' => 100.00,
104 'financial_type_id' => $this->_financialTypeId,
105 'non_deductible_amount' => 10.00,
106 'fee_amount' => 5.00,
107 'net_amount' => 95.00,
108 'source' => 'SSF',
109 'contribution_status_id' => 1,
110 );
111 $this->_processorParams = array(
112 'domain_id' => 1,
113 'name' => 'Dummy',
114 'payment_processor_type_id' => 10,
115 'financial_account_id' => 12,
116 'is_active' => 1,
117 'user_name' => '',
118 'url_site' => 'http://dummy.com',
119 'url_recur' => 'http://dummy.com',
120 'billing_mode' => 1,
121 );
122
123 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
124 $this->paymentInstruments = $instruments['values'];
125 $product1 = $this->callAPISuccess('product', 'create', array(
126 'name' => 'Smurf',
127 'options' => 'brainy smurf, clumsy smurf, papa smurf',
128 ));
129
130 $this->products[] = $product1['values'][$product1['id']];
131 $this->paymentProcessor = $this->dummyProcessorCreate();
132 $processor = $this->paymentProcessor->getPaymentProcessor();
133 $this->paymentProcessorID = $processor['id'];
134 }
135
136 /**
137 * Clean up after each test.
138 */
139 public function tearDown() {
140 $this->quickCleanUpFinancialEntities();
141 $this->quickCleanup(array('civicrm_note', 'civicrm_uf_match', 'civicrm_address'));
142 }
143
144 /**
145 * Test the submit function on the contribution page.
146 */
147 public function testSubmit() {
148 $form = new CRM_Contribute_Form_Contribution();
149 $form->testSubmit(array(
150 'total_amount' => 50,
151 'financial_type_id' => 1,
152 'receive_date' => '04/21/2015',
153 'receive_date_time' => '11:27PM',
154 'contact_id' => $this->_individualId,
155 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
156 'contribution_status_id' => 1,
157 ),
158 CRM_Core_Action::ADD);
159 $contribution = $this->callAPISuccessGetSingle('Contribution', array('contact_id' => $this->_individualId));
160 $this->assertEmpty($contribution['amount_level']);
161 }
162
163 /**
164 * Test the submit function on the contribution page.
165 */
166 public function testSubmitCreditCard() {
167 $form = new CRM_Contribute_Form_Contribution();
168 $form->testSubmit(array(
169 'total_amount' => 50,
170 'financial_type_id' => 1,
171 'receive_date' => '04/21/2015',
172 'receive_date_time' => '11:27PM',
173 'contact_id' => $this->_individualId,
174 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
175 'contribution_status_id' => 1,
176 ), CRM_Core_Action::ADD);
177 $this->callAPISuccessGetCount('Contribution', array(
178 'contact_id' => $this->_individualId,
179 'contribution_status_id' => 'Completed',
180 ),
181 1);
182 }
183
184 /**
185 * Test the submit function on the contribution page.
186 */
187 public function testSubmitCreditCardPayPal() {
188 $form = new CRM_Contribute_Form_Contribution();
189 $paymentProcessorID = $this->paymentProcessorCreate(array('is_test' => 0));
190 $form->_mode = 'Live';
191 $error = FALSE;
192 try {
193 $form->testSubmit(array(
194 'total_amount' => 50,
195 'financial_type_id' => 1,
196 'receive_date' => '04/21/2015',
197 'receive_date_time' => '11:27PM',
198 'contact_id' => $this->_individualId,
199 'contribution_status_id' => 1,
200 'credit_card_number' => 4444333322221111,
201 'cvv2' => 123,
202 'credit_card_exp_date' => array(
203 'M' => 9,
204 'Y' => 2025,
205 ),
206 'credit_card_type' => 'Visa',
207 'billing_first_name' => 'Junko',
208 'billing_middle_name' => '',
209 'billing_last_name' => 'Adams',
210 'billing_street_address-5' => '790L Lincoln St S',
211 'billing_city-5' => 'Maryknoll',
212 'billing_state_province_id-5' => 1031,
213 'billing_postal_code-5' => 10545,
214 'billing_country_id-5' => 1228,
215 'frequency_interval' => 1,
216 'frequency_unit' => 'month',
217 'installments' => '',
218 'hidden_AdditionalDetail' => 1,
219 'hidden_Premium' => 1,
220 'from_email_address' => '"civi45" <civi45@civicrm.com>',
221 'receipt_date' => '',
222 'receipt_date_time' => '',
223 'payment_processor_id' => $paymentProcessorID,
224 'currency' => 'USD',
225 'source' => 'bob sled race',
226 ), CRM_Core_Action::ADD);
227 }
228 catch (Civi\Payment\Exception\PaymentProcessorException $e) {
229 $error = TRUE;
230 }
231
232 $this->callAPISuccessGetCount('Contribution', array(
233 'contact_id' => $this->_individualId,
234 'contribution_status_id' => $error ? 'Failed' : 'Completed',
235 'payment_instrument_id' => $this->callAPISuccessGetValue('PaymentProcessor', array(
236 'return' => 'payment_instrument_id',
237 'id' => $paymentProcessorID,
238 )),
239 ), 1);
240 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $this->_individualId));
241 $this->assertTrue(empty($contact['source']));
242 }
243
244 /**
245 * Test the submit function on the contribution page.
246 */
247 public function testSubmitCreditCardFee() {
248 $form = new CRM_Contribute_Form_Contribution();
249 $this->paymentProcessor->setDoDirectPaymentResult(array('is_error' => 0, 'trxn_id' => 'tx', 'fee_amount' => .08));
250 $form->_mode = 'Live';
251 $form->testSubmit(array(
252 'total_amount' => 50,
253 'financial_type_id' => 1,
254 'receive_date' => '04/21/2015',
255 'receive_date_time' => '11:27PM',
256 'contact_id' => $this->_individualId,
257 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
258 'contribution_status_id' => 1,
259 'credit_card_number' => 4444333322221111,
260 'cvv2' => 123,
261 'credit_card_exp_date' => array(
262 'M' => 9,
263 'Y' => 2025,
264 ),
265 'credit_card_type' => 'Visa',
266 'billing_first_name' => 'Junko',
267 'billing_middle_name' => '',
268 'billing_last_name' => 'Adams',
269 'billing_street_address-5' => '790L Lincoln St S',
270 'billing_city-5' => 'Maryknoll',
271 'billing_state_province_id-5' => 1031,
272 'billing_postal_code-5' => 10545,
273 'billing_country_id-5' => 1228,
274 'frequency_interval' => 1,
275 'frequency_unit' => 'month',
276 'installments' => '',
277 'hidden_AdditionalDetail' => 1,
278 'hidden_Premium' => 1,
279 'from_email_address' => '"civi45" <civi45@civicrm.com>',
280 'receipt_date' => '',
281 'receipt_date_time' => '',
282 'payment_processor_id' => $this->paymentProcessorID,
283 'currency' => 'USD',
284 'source' => '',
285 ), CRM_Core_Action::ADD);
286
287 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
288 'contact_id' => $this->_individualId,
289 'contribution_status_id' => 'Completed',
290 ));
291 $this->assertEquals('50', $contribution['total_amount']);
292 $this->assertEquals(.08, $contribution['fee_amount']);
293 $this->assertEquals(49.92, $contribution['net_amount']);
294 $this->assertEquals('tx', $contribution['trxn_id']);
295 $this->assertEmpty($contribution['amount_level']);
296 }
297
298 /**
299 * Test a fully deductible contribution submitted by credit card (CRM-16669).
300 */
301 public function testSubmitCreditCardFullyDeductible() {
302 $form = new CRM_Contribute_Form_Contribution();
303 $form->_mode = 'Live';
304 $form->testSubmit(array(
305 'total_amount' => 50,
306 'financial_type_id' => 1,
307 'receive_date' => '04/21/2015',
308 'receive_date_time' => '11:27PM',
309 'contact_id' => $this->_individualId,
310 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
311 'contribution_status_id' => 1,
312 'credit_card_number' => 4444333322221111,
313 'cvv2' => 123,
314 'credit_card_exp_date' => array(
315 'M' => 9,
316 'Y' => 2025,
317 ),
318 'credit_card_type' => 'Visa',
319 'billing_first_name' => 'Junko',
320 'billing_middle_name' => '',
321 'billing_last_name' => 'Adams',
322 'billing_street_address-5' => '790L Lincoln St S',
323 'billing_city-5' => 'Maryknoll',
324 'billing_state_province_id-5' => 1031,
325 'billing_postal_code-5' => 10545,
326 'billing_country_id-5' => 1228,
327 'frequency_interval' => 1,
328 'frequency_unit' => 'month',
329 'installments' => '',
330 'hidden_AdditionalDetail' => 1,
331 'hidden_Premium' => 1,
332 'from_email_address' => '"civi45" <civi45@civicrm.com>',
333 'receipt_date' => '',
334 'receipt_date_time' => '',
335 'payment_processor_id' => $this->paymentProcessorID,
336 'currency' => 'USD',
337 'source' => '',
338 ), CRM_Core_Action::ADD);
339
340 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
341 'contact_id' => $this->_individualId,
342 'contribution_status_id' => 'Completed',
343 ));
344 $this->assertEquals('50', $contribution['total_amount']);
345 $this->assertEquals(0, $contribution['non_deductible_amount']);
346 }
347
348 /**
349 * Test the submit function with an invalid payment.
350 *
351 * We expect the contribution to be created but left pending. The payment has failed.
352 *
353 * Test covers CRM-16417 change to keep failed transactions.
354 *
355 * We are left with
356 * - 1 Contribution with status = Pending
357 * - 1 Line item
358 * - 1 civicrm_financial_item. This is linked to the line item and has a status of 3
359 */
360 public function testSubmitCreditCardInvalid() {
361 $form = new CRM_Contribute_Form_Contribution();
362 $this->paymentProcessor->setDoDirectPaymentResult(array('is_error' => 1));
363 try {
364 $form->testSubmit(array(
365 'total_amount' => 50,
366 'financial_type_id' => 1,
367 'receive_date' => '04/21/2015',
368 'receive_date_time' => '11:27PM',
369 'contact_id' => $this->_individualId,
370 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
371 'payment_processor_id' => $this->paymentProcessorID,
372 'credit_card_exp_date' => array('M' => 5, 'Y' => 2012),
373 'credit_card_number' => '411111111111111',
374 ), CRM_Core_Action::ADD,
375 'live'
376 );
377 }
378 catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
379 $this->callAPISuccessGetCount('Contribution', array(
380 'contact_id' => $this->_individualId,
381 'contribution_status_id' => 'Failed',
382 ), 1);
383 $lineItem = $this->callAPISuccessGetSingle('line_item', array());
384 $this->assertEquals('50.00', $lineItem['unit_price']);
385 $this->assertEquals('50.00', $lineItem['line_total']);
386 $this->assertEquals(1, $lineItem['qty']);
387 $this->assertEquals(1, $lineItem['financial_type_id']);
388 $financialItem = $this->callAPISuccessGetSingle('financial_item', array(
389 'civicrm_line_item' => $lineItem['id'],
390 'entity_id' => $lineItem['id'],
391 ));
392 $this->assertEquals('50.00', $financialItem['amount']);
393 $this->assertEquals(3, $financialItem['status_id']);
394 return;
395 }
396 $this->fail('An expected exception has not been raised.');
397 }
398
399 /**
400 * Test the submit function creates a billing address if provided.
401 */
402 public function testSubmitCreditCardWithBillingAddress() {
403 $form = new CRM_Contribute_Form_Contribution();
404 $form->testSubmit(array(
405 'total_amount' => 50,
406 'financial_type_id' => 1,
407 'receive_date' => '04/21/2015',
408 'receive_date_time' => '11:27PM',
409 'contact_id' => $this->_individualId,
410 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
411 'payment_processor_id' => $this->paymentProcessorID,
412 'credit_card_exp_date' => array('M' => 5, 'Y' => 2025),
413 'credit_card_number' => '411111111111111',
414 'billing_city-5' => 'Vancouver',
415 ), CRM_Core_Action::ADD,
416 'live'
417 );
418 $contribution = $this->callAPISuccessGetSingle('Contribution', array('return' => 'address_id'));
419 $this->assertNotEmpty($contribution['address_id']);
420 // CRM-18490 : There is a unwanted test leakage due to below getsingle Api as it only fails in Jenkin
421 // for now we are only fetching address on based on Address ID (removed filter location_type_id and city)
422 $this->callAPISuccessGetSingle('Address', array(
423 'id' => $contribution['address_id'],
424 ));
425
426 }
427
428 /**
429 * Test the submit function does not create a billing address if no details provided.
430 */
431 public function testSubmitCreditCardWithNoBillingAddress() {
432 $form = new CRM_Contribute_Form_Contribution();
433 $form->testSubmit(array(
434 'total_amount' => 50,
435 'financial_type_id' => 1,
436 'receive_date' => '04/21/2015',
437 'receive_date_time' => '11:27PM',
438 'contact_id' => $this->_individualId,
439 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
440 'payment_processor_id' => $this->paymentProcessorID,
441 'credit_card_exp_date' => array('M' => 5, 'Y' => 2025),
442 'credit_card_number' => '411111111111111',
443 ), CRM_Core_Action::ADD,
444 'live'
445 );
446 $contribution = $this->callAPISuccessGetSingle('Contribution', array('return' => 'address_id'));
447 $this->assertEmpty($contribution['address_id']);
448 $this->callAPISuccessGetCount('Address', array(
449 'city' => 'Vancouver',
450 'location_type_id' => 5,
451 ), 0);
452
453 }
454
455 /**
456 * Test the submit function on the contribution page.
457 */
458 public function testSubmitEmailReceipt() {
459 $form = new CRM_Contribute_Form_Contribution();
460 $mut = new CiviMailUtils($this, TRUE);
461 $form->testSubmit(array(
462 'total_amount' => 50,
463 'financial_type_id' => 1,
464 'receive_date' => '04/21/2015',
465 'receive_date_time' => '11:27PM',
466 'contact_id' => $this->_individualId,
467 'is_email_receipt' => TRUE,
468 'from_email_address' => 'test@test.com',
469 'contribution_status_id' => 1,
470 ), CRM_Core_Action::ADD);
471 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
472 $mut->checkMailLog(array(
473 '<p>Please print this receipt for your records.</p>',
474 )
475 );
476 $mut->stop();
477 }
478
479 /**
480 * Ensure that price field are shown during pay later/pending Contribution
481 */
482 public function testEmailReceiptOnPayLater() {
483 $donationFT = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', 'Donation', 'id', 'name');
484 $paramsSet = array(
485 'title' => 'Price Set' . substr(sha1(rand()), 0, 4),
486 'is_active' => TRUE,
487 'financial_type_id' => $donationFT,
488 'extends' => 2,
489 );
490 $paramsSet['name'] = CRM_Utils_String::titleToVar($paramsSet['title']);
491
492 $priceset = CRM_Price_BAO_PriceSet::create($paramsSet);
493 $priceSetId = $priceset->id;
494
495 //Checking for priceset added in the table.
496 $this->assertDBCompareValue('CRM_Price_BAO_PriceSet', $priceSetId, 'title',
497 'id', $paramsSet['title'], 'Check DB for created priceset'
498 );
499 $paramsField = array(
500 'label' => 'Price Field',
501 'name' => CRM_Utils_String::titleToVar('Price Field'),
502 'html_type' => 'CheckBox',
503 'option_label' => array('1' => 'Price Field 1', '2' => 'Price Field 2'),
504 'option_value' => array('1' => 100, '2' => 200),
505 'option_name' => array('1' => 'Price Field 1', '2' => 'Price Field 2'),
506 'option_weight' => array('1' => 1, '2' => 2),
507 'option_amount' => array('1' => 100, '2' => 200),
508 'is_display_amounts' => 1,
509 'weight' => 1,
510 'options_per_line' => 1,
511 'is_active' => array('1' => 1, '2' => 1),
512 'price_set_id' => $priceset->id,
513 'is_enter_qty' => 1,
514 'financial_type_id' => $donationFT,
515 );
516 $priceField = CRM_Price_BAO_PriceField::create($paramsField);
517 $priceFieldValue = $this->callAPISuccess('PriceFieldValue', 'get', array('price_field_id' => $priceField->id));
518
519 $params = array(
520 'total_amount' => 100,
521 'financial_type_id' => $donationFT,
522 'receive_date' => '04/21/2015',
523 'receive_date_time' => '11:27PM',
524 'contact_id' => $this->_individualId,
525 'is_email_receipt' => TRUE,
526 'from_email_address' => 'test@test.com',
527 'price_set_id' => $priceSetId,
528 'contribution_status_id' => CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name'),
529 );
530
531 foreach ($priceFieldValue['values'] as $id => $price) {
532 if ($price['amount'] == 100) {
533 $params['price_' . $priceField->id] = array($id => 1);
534 }
535 }
536 $form = new CRM_Contribute_Form_Contribution();
537 $mut = new CiviMailUtils($this, TRUE);
538 $form->_priceSet = current(CRM_Price_BAO_PriceSet::getSetDetail($priceSetId));
539 $form->testSubmit($params, CRM_Core_Action::ADD);
540
541 $mut->checkMailLog(array(
542 'Financial Type: Donation
543 ---------------------------------------------------------
544 Item Qty Each Total
545 ----------------------------------------------------------
546 Price Field - Price Field 1 1 $ 100.00 $ 100.00
547 ',
548 )
549 );
550 $mut->stop();
551 }
552
553 /**
554 * Test that a contribution is assigned against a pledge.
555 */
556 public function testUpdatePledge() {
557 $pledge = $this->callAPISuccess('pledge', 'create', array(
558 'contact_id' => $this->_individualId,
559 'pledge_create_date' => date('Ymd'),
560 'start_date' => date('Ymd'),
561 'amount' => 100.00,
562 'pledge_status_id' => '2',
563 'pledge_financial_type_id' => '1',
564 'pledge_original_installment_amount' => 20,
565 'frequency_interval' => 5,
566 'frequency_unit' => 'year',
567 'frequency_day' => 15,
568 'installments' => 2,
569 'sequential' => 1,
570 ));
571 $pledgePaymentID = $this->callAPISuccess('pledge_payment', 'getvalue', array(
572 'pledge_id' => $pledge['id'],
573 'options' => array('limit' => 1),
574 'return' => 'id',
575 ));
576 $form = new CRM_Contribute_Form_Contribution();
577 $form->testSubmit(array(
578 'total_amount' => 50,
579 'financial_type_id' => 1,
580 'receive_date' => '04/21/2015',
581 'receive_date_time' => '11:27PM',
582 'contact_id' => $this->_individualId,
583 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
584 'pledge_payment_id' => $pledgePaymentID,
585 'contribution_status_id' => 1,
586 ), CRM_Core_Action::ADD);
587 $pledgePayment = $this->callAPISuccess('pledge_payment', 'getsingle', array('id' => $pledgePaymentID));
588 $this->assertNotEmpty($pledgePayment['contribution_id']);
589 $this->assertEquals($pledgePayment['actual_amount'], 50);
590 $this->assertEquals(1, $pledgePayment['status_id']);
591 }
592
593 /**
594 * Test functions involving premiums.
595 */
596 public function testPremiumUpdate() {
597 $form = new CRM_Contribute_Form_Contribution();
598 $mut = new CiviMailUtils($this, TRUE);
599 $form->testSubmit(array(
600 'total_amount' => 50,
601 'financial_type_id' => 1,
602 'receive_date' => '04/21/2015',
603 'receive_date_time' => '11:27PM',
604 'contact_id' => $this->_individualId,
605 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
606 'contribution_status_id' => 1,
607 'product_name' => array($this->products[0]['id'], 1),
608 'fulfilled_date' => '',
609 'is_email_receipt' => TRUE,
610 'from_email_address' => 'test@test.com',
611 ), CRM_Core_Action::ADD);
612 $contributionProduct = $this->callAPISuccess('contribution_product', 'getsingle', array());
613 $this->assertEquals('clumsy smurf', $contributionProduct['product_option']);
614 $mut->checkMailLog(array(
615 'Premium Information',
616 'Smurf',
617 'clumsy smurf',
618 ));
619 $mut->stop();
620 }
621
622 /**
623 * Test functions involving premiums.
624 */
625 public function testPremiumUpdateCreditCard() {
626 $form = new CRM_Contribute_Form_Contribution();
627 $mut = new CiviMailUtils($this, TRUE);
628 $form->testSubmit(array(
629 'total_amount' => 50,
630 'financial_type_id' => 1,
631 'receive_date' => '04/21/2015',
632 'receive_date_time' => '11:27PM',
633 'contact_id' => $this->_individualId,
634 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
635 'contribution_status_id' => 1,
636 'product_name' => array($this->products[0]['id'], 1),
637 'fulfilled_date' => '',
638 'is_email_receipt' => TRUE,
639 'from_email_address' => 'test@test.com',
640 'payment_processor_id' => $this->paymentProcessorID,
641 'credit_card_exp_date' => array('M' => 5, 'Y' => 2026),
642 'credit_card_number' => '411111111111111',
643 ), CRM_Core_Action::ADD,
644 'live');
645 $contributionProduct = $this->callAPISuccess('contribution_product', 'getsingle', array());
646 $this->assertEquals('clumsy smurf', $contributionProduct['product_option']);
647 $mut->checkMailLog(array(
648 'Premium Information',
649 'Smurf',
650 'clumsy smurf',
651 ));
652 $mut->stop();
653 }
654
655 /**
656 * Test the submit function on the contribution page.
657 */
658 public function testSubmitWithNote() {
659 $form = new CRM_Contribute_Form_Contribution();
660 $form->testSubmit(array(
661 'total_amount' => 50,
662 'financial_type_id' => 1,
663 'receive_date' => '04/21/2015',
664 'receive_date_time' => '11:27PM',
665 'contact_id' => $this->_individualId,
666 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
667 'contribution_status_id' => 1,
668 'note' => 'Super cool and interesting stuff',
669 ),
670 CRM_Core_Action::ADD);
671 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
672 $note = $this->callAPISuccessGetSingle('note', array('entity_table' => 'civicrm_contribution'));
673 $this->assertEquals($note['note'], 'Super cool and interesting stuff');
674 }
675
676 /**
677 * Test the submit function on the contribution page.
678 */
679 public function testSubmitWithNoteCreditCard() {
680 $form = new CRM_Contribute_Form_Contribution();
681
682 $form->testSubmit(array(
683 'total_amount' => 50,
684 'financial_type_id' => 1,
685 'receive_date' => '04/21/2015',
686 'receive_date_time' => '11:27PM',
687 'contact_id' => $this->_individualId,
688 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
689 'contribution_status_id' => 1,
690 'note' => 'Super cool and interesting stuff',
691 ) + $this->getCreditCardParams(),
692 CRM_Core_Action::ADD);
693 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
694 $note = $this->callAPISuccessGetSingle('note', array('entity_table' => 'civicrm_contribution'));
695 $this->assertEquals($note['note'], 'Super cool and interesting stuff');
696 }
697
698 /**
699 * Test that if a negative contribution is entered it does not get reset to $0
700 */
701 public function testEnterNegativeContribution() {
702 $form = new CRM_Contribute_Form_Contribution();
703 $form->testSubmit(array(
704 'total_amount' => -5,
705 'financial_type_id' => 1,
706 'receive_date' => '04/24/2016',
707 'receive_date_time' => '11:27PM',
708 'contact_id' => $this->_individualId,
709 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
710 'contribution_status_id' => 1,
711 ),
712 CRM_Core_Action::ADD);
713 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
714
715 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
716 'contact_id' => $this->_individualId,
717 ));
718 $this->assertEquals(-5, $contribution['total_amount']);
719 }
720
721 /**
722 * Test the submit function on the contribution page.
723 */
724 public function testSubmitUpdate() {
725 $form = new CRM_Contribute_Form_Contribution();
726
727 $form->testSubmit(array(
728 'total_amount' => 50,
729 'financial_type_id' => 1,
730 'receive_date' => '04/21/2015',
731 'receive_date_time' => '11:27PM',
732 'contact_id' => $this->_individualId,
733 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
734 'contribution_status_id' => 1,
735 'price_set_id' => 0,
736 ),
737 CRM_Core_Action::ADD);
738 $contribution = $this->callAPISuccessGetSingle('Contribution', array('contact_id' => $this->_individualId));
739 $form->testSubmit(array(
740 'total_amount' => 45,
741 'net_amount' => 45,
742 'financial_type_id' => 1,
743 'receive_date' => '04/21/2015',
744 'receive_date_time' => '11:27PM',
745 'contact_id' => $this->_individualId,
746 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
747 'contribution_status_id' => 1,
748 'price_set_id' => 0,
749 'id' => $contribution['id'],
750 ),
751 CRM_Core_Action::UPDATE);
752 $contribution = $this->callAPISuccessGetSingle('Contribution', array('contact_id' => $this->_individualId));
753 $this->assertEquals(45, (int) $contribution['total_amount']);
754
755 $financialTransactions = $this->callAPISuccess('FinancialTrxn', 'get', array('sequential' => TRUE));
756 $this->assertEquals(2, $financialTransactions['count']);
757 $this->assertEquals(50, $financialTransactions['values'][0]['total_amount']);
758 $this->assertEquals(-5, $financialTransactions['values'][1]['total_amount']);
759 $this->assertEquals(-5, $financialTransactions['values'][1]['net_amount']);
760 $lineItem = $this->callAPISuccessGetSingle('LineItem', array());
761 $this->assertEquals(45, $lineItem['line_total']);
762 }
763
764 /**
765 * Get parameters for credit card submit calls.
766 *
767 * @return array
768 * Credit card specific parameters.
769 */
770 protected function getCreditCardParams() {
771 return array(
772 'payment_processor_id' => $this->paymentProcessorID,
773 'credit_card_exp_date' => array('M' => 5, 'Y' => 2012),
774 'credit_card_number' => '411111111111111',
775 );
776 }
777
778 /**
779 * Test the submit function for FT with tax.
780 */
781 public function testSubmitSaleTax() {
782 $this->enableTaxAndInvoicing();
783 $this->relationForFinancialTypeWithFinancialAccount($this->_financialTypeId);
784 $form = new CRM_Contribute_Form_Contribution();
785
786 $form->testSubmit(array(
787 'total_amount' => 100,
788 'financial_type_id' => $this->_financialTypeId,
789 'receive_date' => '04/21/2015',
790 'receive_date_time' => '11:27PM',
791 'contact_id' => $this->_individualId,
792 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
793 'contribution_status_id' => 1,
794 'price_set_id' => 0,
795 ),
796 CRM_Core_Action::ADD
797 );
798 $contribution = $this->callAPISuccessGetSingle('Contribution',
799 array(
800 'contact_id' => $this->_individualId,
801 'return' => array('tax_amount', 'total_amount'),
802 )
803 );
804 $this->assertEquals(110, $contribution['total_amount']);
805 $this->assertEquals(10, $contribution['tax_amount']);
806 $this->callAPISuccessGetCount('FinancialTrxn', array(), 1);
807 $this->callAPISuccessGetCount('FinancialItem', array(), 2);
808 $lineItem = $this->callAPISuccessGetSingle('LineItem', array('contribution_id' => $contribution['id']));
809 $this->assertEquals(100, $lineItem['line_total']);
810 $this->assertEquals(10, $lineItem['tax_amount']);
811 }
812
813 /**
814 * Test the submit function for FT without tax.
815 */
816 public function testSubmitWithOutSaleTax() {
817 $this->enableTaxAndInvoicing();
818 $this->relationForFinancialTypeWithFinancialAccount($this->_financialTypeId);
819 $form = new CRM_Contribute_Form_Contribution();
820
821 $form->testSubmit(array(
822 'total_amount' => 100,
823 'financial_type_id' => 3,
824 'receive_date' => '04/21/2015',
825 'receive_date_time' => '11:27PM',
826 'contact_id' => $this->_individualId,
827 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
828 'contribution_status_id' => 1,
829 'price_set_id' => 0,
830 ),
831 CRM_Core_Action::ADD
832 );
833 $contribution = $this->callAPISuccessGetSingle('Contribution',
834 array(
835 'contact_id' => $this->_individualId,
836 'return' => array('tax_amount', 'total_amount'),
837 )
838 );
839 $this->assertEquals(100, $contribution['total_amount']);
840 $this->assertEquals(NULL, $contribution['tax_amount']);
841 $this->callAPISuccessGetCount('FinancialTrxn', array(), 1);
842 $this->callAPISuccessGetCount('FinancialItem', array(), 1);
843 $lineItem = $this->callAPISuccessGetSingle(
844 'LineItem',
845 array(
846 'contribution_id' => $contribution['id'],
847 'return' => array('line_total', 'tax_amount'),
848 )
849 );
850 $this->assertEquals(100, $lineItem['line_total']);
851 $this->assertTrue(empty($lineItem['tax_amount']));
852 }
853
854 /**
855 * Create a contribution & then edit it via backoffice form, checking tax with: default price_set
856 *
857 * @throws \Exception
858 */
859 public function testReSubmitSaleTax() {
860 $this->enableTaxAndInvoicing();
861 $this->relationForFinancialTypeWithFinancialAccount($this->_financialTypeId);
862 $form = new CRM_Contribute_Form_Contribution();
863
864 $form->testSubmit(array(
865 'total_amount' => 100,
866 'financial_type_id' => $this->_financialTypeId,
867 'receive_date' => '04/21/2015',
868 'receive_date_time' => '11:27PM',
869 'contact_id' => $this->_individualId,
870 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
871 'contribution_status_id' => 1,
872 'price_set_id' => 0,
873 ),
874 CRM_Core_Action::ADD
875 );
876 $contribution = $this->callAPISuccessGetSingle('Contribution',
877 array(
878 'contribution_id' => 1,
879 'return' => array('tax_amount', 'total_amount', 'net_amount', 'financial_type_id', 'receive_date', 'payment_instrument_id'),
880 )
881 );
882 $this->assertEquals(110, $contribution['total_amount']);
883 $this->assertEquals(10, $contribution['tax_amount']);
884 $this->assertEquals(110, $contribution['net_amount']);
885
886 $mut = new CiviMailUtils($this, TRUE);
887 // Testing here if when we edit something trivial like adding a check_number tax, net, total amount stay the same:
888 $form->testSubmit(array(
889 'id' => $contribution['id'],
890 'tax_amount' => $contribution['tax_amount'],
891 'financial_type_id' => $contribution['financial_type_id'],
892 'receive_date' => $contribution['receive_date'],
893 'payment_instrument_id' => $contribution['payment_instrument_id'],
894 'price_set_id' => 0,
895 'check_number' => 12345,
896 'contribution_status_id' => 1,
897 'is_email_receipt' => 1,
898 'from_email_address' => 'demo@example.com',
899 ),
900 CRM_Core_Action::UPDATE
901 );
902 $contribution = $this->callAPISuccessGetSingle('Contribution',
903 array(
904 'contribution_id' => 1,
905 'return' => array('tax_amount', 'total_amount', 'net_amount', 'financial_type_id', 'receive_date', 'payment_instrument_id'),
906 )
907 );
908 $this->assertEquals(110, $contribution['total_amount']);
909 $this->assertEquals(10, $contribution['tax_amount']);
910 $this->assertEquals(110, $contribution['net_amount']);
911
912 $strings = array(
913 'Total Tax Amount : $ 10.00',
914 'Total Amount : $ 110.00',
915 'Date Received: April 21st, 2015',
916 'Paid By: Check',
917 'Check Number: 12345',
918 );
919
920 $mut->checkMailLog($strings);
921 $this->callAPISuccessGetCount('FinancialTrxn', array(), 3);
922 $this->callAPISuccessGetCount('FinancialItem', array(), 2);
923 }
924
925 /**
926 * function to test card_type and pan truncation.
927 */
928 public function testCardTypeAndPanTruncation() {
929 $form = new CRM_Contribute_Form_Contribution();
930 $form->testSubmit(
931 array(
932 'total_amount' => 100,
933 'financial_type_id' => 3,
934 'receive_date' => '04/21/2015',
935 'receive_date_time' => '11:27PM',
936 'contact_id' => $this->_individualId,
937 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
938 'contribution_status_id' => 1,
939 'credit_card_type' => 'Visa',
940 'pan_truncation' => 4567,
941 'price_set_id' => 0,
942 ),
943 CRM_Core_Action::ADD
944 );
945 $contribution = $this->callAPISuccessGetSingle('Contribution',
946 array(
947 'contact_id' => $this->_individualId,
948 'return' => array('id'),
949 )
950 );
951 $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
952 $financialTrxn = $this->callAPISuccessGetSingle(
953 'FinancialTrxn',
954 array(
955 'id' => $lastFinancialTrxnId['financialTrxnId'],
956 'return' => array('card_type_id.label', 'pan_truncation'),
957 )
958 );
959 $this->assertEquals(CRM_Utils_Array::value('card_type_id.label', $financialTrxn), 'Visa');
960 $this->assertEquals(CRM_Utils_Array::value('pan_truncation', $financialTrxn), 4567);
961 }
962
963 /**
964 * function to test card_type and pan truncation.
965 */
966 public function testCardTypeAndPanTruncationLiveMode() {
967 $visaID = CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_FinancialTrxn', 'card_type_id', 'Visa');
968 $form = new CRM_Contribute_Form_Contribution();
969 $form->_mode = 'Live';
970 $form->testSubmit(
971 array(
972 'total_amount' => 50,
973 'financial_type_id' => 1,
974 'receive_date' => '04/21/2015',
975 'receive_date_time' => '11:27PM',
976 'contact_id' => $this->_individualId,
977 'credit_card_number' => 4444333322221111,
978 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
979 'cvv2' => 123,
980 'credit_card_exp_date' => array(
981 'M' => 9,
982 'Y' => date('Y', strtotime('+5 years')),
983 ),
984 'credit_card_type' => 'Visa',
985 'billing_first_name' => 'Junko',
986 'billing_middle_name' => '',
987 'billing_last_name' => 'Adams',
988 'billing_street_address-5' => '790L Lincoln St S',
989 'billing_city-5' => 'Maryknoll',
990 'billing_state_province_id-5' => 1031,
991 'billing_postal_code-5' => 10545,
992 'billing_country_id-5' => 1228,
993 'frequency_interval' => 1,
994 'frequency_unit' => 'month',
995 'installments' => '',
996 'hidden_AdditionalDetail' => 1,
997 'hidden_Premium' => 1,
998 'from_email_address' => '"civi45" <civi45@civicrm.com>',
999 'receipt_date' => '',
1000 'receipt_date_time' => '',
1001 'payment_processor_id' => $this->paymentProcessorID,
1002 'currency' => 'USD',
1003 'source' => 'bob sled race',
1004 ),
1005 CRM_Core_Action::ADD
1006 );
1007 $contribution = $this->callAPISuccessGetSingle('Contribution', array('contact_id' => $this->_individualId));
1008 $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
1009 $financialTrxn = $this->callAPISuccessGetSingle(
1010 'FinancialTrxn',
1011 array(
1012 'id' => $lastFinancialTrxnId['financialTrxnId'],
1013 'return' => array('card_type_id', 'pan_truncation'),
1014 )
1015 );
1016 $this->assertEquals($visaID, $financialTrxn['card_type_id']);
1017 $this->assertEquals(1111, $financialTrxn['pan_truncation']);
1018 }
1019
1020 }