Merge pull request #6538 from systopia/CRM-17047
[civicrm-core.git] / tests / phpunit / CRM / Contribute / Form / ContributionTest.php
CommitLineData
a084385f
EM
1<?php
2/*
3 +--------------------------------------------------------------------+
81621fee 4 | CiviCRM version 4.7 |
a084385f
EM
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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
28require_once 'CiviTest/CiviUnitTestCase.php';
29require_once 'CiviTest/CiviMailUtils.php';
30
31
32/**
33 * Test APIv3 civicrm_contribute_* functions
34 *
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contribution
37 */
38class CRM_Contribute_Form_ContributionTest extends CiviUnitTestCase {
39
40 /**
41 * Assume empty database with just civicrm_data.
42 */
43 protected $_individualId;
44 protected $_contribution;
45 protected $_financialTypeId = 1;
46 protected $_apiversion;
47 protected $_entity = 'Contribution';
48 protected $_params;
49 protected $_ids = array();
50 protected $_pageParams = array();
51
52 /**
53 * Parameters to create payment processor.
54 *
55 * @var array
56 */
57 protected $_processorParams = array();
58
59 /**
60 * ID of created event.
61 *
62 * @var int
63 */
64 protected $_eventID;
65
66 /**
67 * Payment instrument mapping.
68 *
69 * @var array
70 */
71 protected $paymentInstruments = array();
72
3e6a1f4a
EM
73 /**
74 * Products.
75 *
76 * @var array
77 */
78 protected $products = array();
79
39f47c0d
EM
80 /**
81 * Dummy payment processor.
82 *
7758bd2b 83 * @var CRM_Core_Payment_Dummy
39f47c0d 84 */
7758bd2b 85 protected $paymentProcessor;
39f47c0d 86
a084385f
EM
87 /**
88 * Setup function.
89 */
90 public function setUp() {
39f47c0d 91 $this->_apiversion = 3;
a084385f 92 parent::setUp();
39f47c0d 93 $this->createLoggedInUser();
a084385f 94
a084385f 95 $this->_individualId = $this->individualCreate();
a084385f
EM
96 $this->_params = array(
97 'contact_id' => $this->_individualId,
98 'receive_date' => '20120511',
99 'total_amount' => 100.00,
100 'financial_type_id' => $this->_financialTypeId,
101 'non_deductible_amount' => 10.00,
102 'fee_amount' => 5.00,
103 'net_amount' => 95.00,
104 'source' => 'SSF',
105 'contribution_status_id' => 1,
106 );
107 $this->_processorParams = array(
108 'domain_id' => 1,
109 'name' => 'Dummy',
110 'payment_processor_type_id' => 10,
111 'financial_account_id' => 12,
112 'is_active' => 1,
113 'user_name' => '',
114 'url_site' => 'http://dummy.com',
115 'url_recur' => 'http://dummy.com',
116 'billing_mode' => 1,
117 );
7758bd2b 118
a084385f
EM
119 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
120 $this->paymentInstruments = $instruments['values'];
3e6a1f4a
EM
121 $product1 = $this->callAPISuccess('product', 'create', array(
122 'name' => 'Smurf',
123 'options' => 'brainy smurf, clumsy smurf, papa smurf',
124 ));
125
126 $this->products[] = $product1['values'][$product1['id']];
39f47c0d
EM
127 $this->paymentProcessor = $this->processorCreate();
128
a084385f
EM
129 }
130
131 /**
132 * Clean up after each test.
133 */
134 public function tearDown() {
135 $this->quickCleanUpFinancialEntities();
739a8336 136 $this->quickCleanup(array('civicrm_note', 'civicrm_uf_match', 'civicrm_address'));
a084385f
EM
137 }
138
139 /**
140 * Test the submit function on the contribution page.
141 */
142 public function testSubmit() {
143 $form = new CRM_Contribute_Form_Contribution();
144 $form->testSubmit(array(
145 'total_amount' => 50,
146 'financial_type_id' => 1,
147 'receive_date' => '04/21/2015',
148 'receive_date_time' => '11:27PM',
149 'contact_id' => $this->_individualId,
150 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
5e27919e 151 'contribution_status_id' => 1,
31760f81
EM
152 ),
153 CRM_Core_Action::ADD);
a084385f
EM
154 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
155 }
156
157 /**
158 * Test the submit function on the contribution page.
159 */
160 public function testSubmitCreditCard() {
161 $form = new CRM_Contribute_Form_Contribution();
162 $form->testSubmit(array(
163 'total_amount' => 50,
164 'financial_type_id' => 1,
165 'receive_date' => '04/21/2015',
166 'receive_date_time' => '11:27PM',
167 'contact_id' => $this->_individualId,
168 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
5e27919e 169 'contribution_status_id' => 1,
31760f81 170 ), CRM_Core_Action::ADD);
7758bd2b
EM
171 $this->callAPISuccessGetCount('Contribution', array(
172 'contact_id' => $this->_individualId,
173 'contribution_status_id' => 'Completed',
174 ),
175 1);
a084385f
EM
176 }
177
7126b55c 178 /**
7758bd2b
EM
179 * Test the submit function with an invalid payment.
180 *
181 * We expect the contribution to be created but left pending. The payment has failed.
182 *
183 * Test covers CRM-16417 change to keep failed transactions.
184 *
185 * We are left with
186 * - 1 Contribution with status = Pending
187 * - 1 Line item
188 * - 1 civicrm_financial_item. This is linked to the line item and has a status of 3
7126b55c 189 */
7758bd2b 190 public function testSubmitCreditCardInvalid() {
7126b55c 191 $form = new CRM_Contribute_Form_Contribution();
7758bd2b
EM
192 $this->paymentProcessor->setDoDirectPaymentResult(array('is_error' => 1));
193 try {
194 $form->testSubmit(array(
195 'total_amount' => 50,
196 'financial_type_id' => 1,
197 'receive_date' => '04/21/2015',
198 'receive_date_time' => '11:27PM',
199 'contact_id' => $this->_individualId,
200 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
201 'payment_processor_id' => $this->paymentProcessor->id,
202 'credit_card_exp_date' => array('M' => 5, 'Y' => 2012),
203 'credit_card_number' => '411111111111111',
204 ), CRM_Core_Action::ADD,
739a8336 205 'live'
206 );
7758bd2b
EM
207 }
208 catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
40f5ec68
EM
209 $this->callAPISuccessGetCount('Contribution', array(
210 'contact_id' => $this->_individualId,
211 'contribution_status_id' => 'Pending',
212 ), 1);
7758bd2b
EM
213 $lineItem = $this->callAPISuccessGetSingle('line_item', array());
214 $this->assertEquals('50.00', $lineItem['unit_price']);
215 $this->assertEquals('50.00', $lineItem['line_total']);
216 $this->assertEquals(1, $lineItem['qty']);
217 $this->assertEquals(1, $lineItem['financial_type_id']);
218 $financialItem = $this->callAPISuccessGetSingle('financial_item', array(
219 'civicrm_line_item' => $lineItem['id'],
220 'entity_id' => $lineItem['id'],
221 ));
222 $this->assertEquals('50.00', $financialItem['amount']);
223 $this->assertEquals(3, $financialItem['status_id']);
224 return;
225 }
226 $this->fail('An expected exception has not been raised.');
7126b55c
EM
227 }
228
739a8336 229 /**
230 * Test the submit function creates a billing address if provided.
231 */
232 public function testSubmitCreditCardWithBillingAddress() {
233 $form = new CRM_Contribute_Form_Contribution();
234 $form->testSubmit(array(
235 'total_amount' => 50,
236 'financial_type_id' => 1,
237 'receive_date' => '04/21/2015',
238 'receive_date_time' => '11:27PM',
239 'contact_id' => $this->_individualId,
240 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
241 'payment_processor_id' => $this->paymentProcessor->id,
242 'credit_card_exp_date' => array('M' => 5, 'Y' => 2025),
243 'credit_card_number' => '411111111111111',
244 'billing_city-5' => 'Vancouver',
245 ), CRM_Core_Action::ADD,
246 'live'
247 );
248 $contribution = $this->callAPISuccessGetSingle('Contribution', array('return' => 'address_id'));
249 $this->assertNotEmpty($contribution['address_id']);
250 $this->callAPISuccessGetSingle('Address', array(
251 'city' => 'Vancouver',
252 'location_type_id' => 5,
253 'id' => $contribution['address_id'],
254 ));
255
256 }
257
258 /**
259 * Test the submit function does not create a billing address if no details provided.
260 */
261 public function testSubmitCreditCardWithNoBillingAddress() {
262 $form = new CRM_Contribute_Form_Contribution();
263 $form->testSubmit(array(
264 'total_amount' => 50,
265 'financial_type_id' => 1,
266 'receive_date' => '04/21/2015',
267 'receive_date_time' => '11:27PM',
268 'contact_id' => $this->_individualId,
269 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
270 'payment_processor_id' => $this->paymentProcessor->id,
271 'credit_card_exp_date' => array('M' => 5, 'Y' => 2025),
272 'credit_card_number' => '411111111111111',
273 ), CRM_Core_Action::ADD,
274 'live'
275 );
276 $contribution = $this->callAPISuccessGetSingle('Contribution', array('return' => 'address_id'));
277 $this->assertEmpty($contribution['address_id']);
278 $this->callAPISuccessGetCount('Address', array(
279 'city' => 'Vancouver',
280 'location_type_id' => 5,
281 ), 0);
282
283 }
284
a084385f
EM
285 /**
286 * Test the submit function on the contribution page.
287 */
288 public function testSubmitEmailReceipt() {
289 $form = new CRM_Contribute_Form_Contribution();
290 require_once 'CiviTest/CiviMailUtils.php';
291 $mut = new CiviMailUtils($this, TRUE);
292 $form->testSubmit(array(
293 'total_amount' => 50,
294 'financial_type_id' => 1,
295 'receive_date' => '04/21/2015',
296 'receive_date_time' => '11:27PM',
297 'contact_id' => $this->_individualId,
298 'is_email_receipt' => TRUE,
299 'from_email_address' => 'test@test.com',
5e27919e 300 'contribution_status_id' => 1,
31760f81 301 ), CRM_Core_Action::ADD);
a084385f
EM
302 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
303 $mut->checkMailLog(array(
304 '<p>Please print this receipt for your records.</p>',
305 )
306 );
307 $mut->stop();
308 }
df729ab1 309
31760f81
EM
310 /**
311 * Test that a contribution is assigned against a pledge.
312 */
313 public function testUpdatePledge() {
314 $pledge = $this->callAPISuccess('pledge', 'create', array(
315 'contact_id' => $this->_individualId,
316 'pledge_create_date' => date('Ymd'),
317 'start_date' => date('Ymd'),
318 'amount' => 100.00,
319 'pledge_status_id' => '2',
320 'pledge_financial_type_id' => '1',
321 'pledge_original_installment_amount' => 20,
322 'frequency_interval' => 5,
323 'frequency_unit' => 'year',
324 'frequency_day' => 15,
325 'installments' => 2,
326 'sequential' => 1,
327 ));
328 $pledgePaymentID = $this->callAPISuccess('pledge_payment', 'getvalue', array(
329 'pledge_id' => $pledge['id'],
330 'options' => array('limit' => 1),
331 'return' => 'id',
332 ));
333 $form = new CRM_Contribute_Form_Contribution();
334 $form->testSubmit(array(
335 'total_amount' => 50,
336 'financial_type_id' => 1,
337 'receive_date' => '04/21/2015',
338 'receive_date_time' => '11:27PM',
339 'contact_id' => $this->_individualId,
340 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
341 'pledge_payment_id' => $pledgePaymentID,
5e27919e 342 'contribution_status_id' => 1,
31760f81
EM
343 ), CRM_Core_Action::ADD);
344 $pledgePayment = $this->callAPISuccess('pledge_payment', 'getsingle', array('id' => $pledgePaymentID));
345 $this->assertNotEmpty($pledgePayment['contribution_id']);
346 $this->assertEquals($pledgePayment['actual_amount'], 50);
347 $this->assertEquals(1, $pledgePayment['status_id']);
348 }
ef353929 349
3e6a1f4a
EM
350 /**
351 * Test functions involving premiums.
352 */
353 public function testPremiumUpdate() {
354 $form = new CRM_Contribute_Form_Contribution();
43bf07d6 355 $mut = new CiviMailUtils($this, TRUE);
3e6a1f4a
EM
356 $form->testSubmit(array(
357 'total_amount' => 50,
358 'financial_type_id' => 1,
359 'receive_date' => '04/21/2015',
360 'receive_date_time' => '11:27PM',
361 'contact_id' => $this->_individualId,
362 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
363 'contribution_status_id' => 1,
364 'product_name' => array($this->products[0]['id'], 1),
365 'fulfilled_date' => '',
43bf07d6
EM
366 'is_email_receipt' => TRUE,
367 'from_email_address' => 'test@test.com',
3e6a1f4a
EM
368 ), CRM_Core_Action::ADD);
369 $contributionProduct = $this->callAPISuccess('contribution_product', 'getsingle', array());
370 $this->assertEquals('clumsy smurf', $contributionProduct['product_option']);
43bf07d6
EM
371 $mut->checkMailLog(array(
372 'Premium Information',
373 'Smurf',
374 'clumsy smurf',
375 ));
376 $mut->stop();
3e6a1f4a
EM
377 }
378
39f47c0d
EM
379 /**
380 * Test functions involving premiums.
381 */
382 public function testPremiumUpdateCreditCard() {
383 $form = new CRM_Contribute_Form_Contribution();
384 $mut = new CiviMailUtils($this, TRUE);
385 $form->testSubmit(array(
386 'total_amount' => 50,
387 'financial_type_id' => 1,
388 'receive_date' => '04/21/2015',
389 'receive_date_time' => '11:27PM',
390 'contact_id' => $this->_individualId,
391 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
392 'contribution_status_id' => 1,
393 'product_name' => array($this->products[0]['id'], 1),
394 'fulfilled_date' => '',
395 'is_email_receipt' => TRUE,
396 'from_email_address' => 'test@test.com',
397 'payment_processor_id' => $this->paymentProcessor->id,
7758bd2b 398 'credit_card_exp_date' => array('M' => 5, 'Y' => 2026),
39f47c0d
EM
399 'credit_card_number' => '411111111111111',
400 ), CRM_Core_Action::ADD,
401 'live');
402 $contributionProduct = $this->callAPISuccess('contribution_product', 'getsingle', array());
403 $this->assertEquals('clumsy smurf', $contributionProduct['product_option']);
404 $mut->checkMailLog(array(
405 'Premium Information',
406 'Smurf',
407 'clumsy smurf',
408 ));
409 $mut->stop();
410 }
411
945f423d
EM
412 /**
413 * Test the submit function on the contribution page.
414 */
415 public function testSubmitWithNote() {
416 $form = new CRM_Contribute_Form_Contribution();
417 $form->testSubmit(array(
418 'total_amount' => 50,
419 'financial_type_id' => 1,
420 'receive_date' => '04/21/2015',
421 'receive_date_time' => '11:27PM',
422 'contact_id' => $this->_individualId,
423 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
424 'contribution_status_id' => 1,
425 'note' => 'Super cool and interesting stuff',
426 ),
427 CRM_Core_Action::ADD);
428 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
429 $note = $this->callAPISuccessGetSingle('note', array('entity_table' => 'civicrm_contribution'));
430 $this->assertEquals($note['note'], 'Super cool and interesting stuff');
431 }
432
433 /**
434 * Test the submit function on the contribution page.
435 */
436 public function testSubmitWithNoteCreditCard() {
437 $form = new CRM_Contribute_Form_Contribution();
438
439 $form->testSubmit(array(
440 'total_amount' => 50,
441 'financial_type_id' => 1,
442 'receive_date' => '04/21/2015',
443 'receive_date_time' => '11:27PM',
444 'contact_id' => $this->_individualId,
445 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
446 'contribution_status_id' => 1,
447 'note' => 'Super cool and interesting stuff',
1ea0b4ac 448 ) + $this->getCreditCardParams(),
945f423d
EM
449 CRM_Core_Action::ADD);
450 $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1);
451 $note = $this->callAPISuccessGetSingle('note', array('entity_table' => 'civicrm_contribution'));
452 $this->assertEquals($note['note'], 'Super cool and interesting stuff');
453 }
454
55e55e84 455 /**
456 * Test the submit function on the contribution page.
457 */
458 public function testSubmitUpdate() {
459 $form = new CRM_Contribute_Form_Contribution();
460
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 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
468 'contribution_status_id' => 1,
469 'price_set_id' => 0,
470 ),
471 CRM_Core_Action::ADD);
472 $contribution = $this->callAPISuccessGetSingle('Contribution', array('contact_id' => $this->_individualId));
473 $form->testSubmit(array(
474 'total_amount' => 45,
475 'net_amount' => 45,
476 'financial_type_id' => 1,
477 'receive_date' => '04/21/2015',
478 'receive_date_time' => '11:27PM',
479 'contact_id' => $this->_individualId,
480 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
481 'contribution_status_id' => 1,
482 'price_set_id' => 0,
483 'id' => $contribution['id'],
484 ),
485 CRM_Core_Action::UPDATE);
da77cbbd
EM
486 $contribution = $this->callAPISuccessGetSingle('Contribution', array('contact_id' => $this->_individualId));
487 $this->assertEquals(45, (int) $contribution['total_amount']);
488
55e55e84 489 $financialTransactions = $this->callAPISuccess('FinancialTrxn', 'get', array('sequential' => TRUE));
490 $this->assertEquals(2, $financialTransactions['count']);
491 $this->assertEquals(50, $financialTransactions['values'][0]['total_amount']);
a4ed7706
EM
492 $this->assertEquals(-5, $financialTransactions['values'][1]['total_amount']);
493 $this->assertEquals(-5, $financialTransactions['values'][1]['net_amount']);
55e55e84 494 $lineItem = $this->callAPISuccessGetSingle('LineItem', array());
495 $this->assertEquals(45, $lineItem['line_total']);
496 }
497
498
945f423d
EM
499 /**
500 * Get parameters for credit card submit calls.
501 *
502 * @return array
503 * Credit card specific parameters.
504 */
1ea0b4ac 505 protected function getCreditCardParams() {
945f423d
EM
506 return array(
507 'payment_processor_id' => $this->paymentProcessor->id,
508 'credit_card_exp_date' => array('M' => 5, 'Y' => 2012),
509 'credit_card_number' => '411111111111111',
510 );
511 }
945f423d 512
2dcbf765 513}