CRM-19298 - hopefully last syntax error
[civicrm-core.git] / tests / phpunit / api / v3 / ContributionPageTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
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_recur* functions
30 *
31 * @package CiviCRM_APIv3
32 * @subpackage API_Contribution
33 * @group headless
34 */
35 class api_v3_ContributionPageTest extends CiviUnitTestCase {
36 protected $_apiversion = 3;
37 protected $testAmount = 34567;
38 protected $params;
39 protected $id = 0;
40 protected $contactIds = array();
41 protected $_entity = 'contribution_page';
42 protected $contribution_result = NULL;
43 protected $_priceSetParams = array();
44 /**
45 * Payment processor details.
46 * @var array
47 */
48 protected $_paymentProcessor = array();
49
50 /**
51 * @var array
52 * - contribution_page
53 * - price_set
54 * - price_field
55 * - price_field_value
56 */
57 protected $_ids = array();
58
59
60 public $DBResetRequired = TRUE;
61
62 public function setUp() {
63 parent::setUp();
64 $this->contactIds[] = $this->individualCreate();
65 $this->params = array(
66 'title' => "Test Contribution Page",
67 'financial_type_id' => 1,
68 'currency' => 'NZD',
69 'goal_amount' => $this->testAmount,
70 'is_pay_later' => 1,
71 'is_monetary' => TRUE,
72 'is_email_receipt' => TRUE,
73 'receipt_from_email' => 'yourconscience@donate.com',
74 'receipt_from_name' => 'Ego Freud',
75 );
76
77 $this->_priceSetParams = array(
78 'is_quick_config' => 1,
79 'extends' => 'CiviContribute',
80 'financial_type_id' => 'Donation',
81 'title' => 'my Page',
82 );
83 }
84
85 public function tearDown() {
86 foreach ($this->contactIds as $id) {
87 $this->callAPISuccess('contact', 'delete', array('id' => $id));
88 }
89 $this->quickCleanUpFinancialEntities();
90 }
91
92 public function testCreateContributionPage() {
93 $result = $this->callAPIAndDocument($this->_entity, 'create', $this->params, __FUNCTION__, __FILE__);
94 $this->assertEquals(1, $result['count']);
95 $this->assertNotNull($result['values'][$result['id']]['id']);
96 $this->getAndCheck($this->params, $result['id'], $this->_entity);
97 }
98
99 public function testGetBasicContributionPage() {
100 $createResult = $this->callAPISuccess($this->_entity, 'create', $this->params);
101 $this->id = $createResult['id'];
102 $getParams = array(
103 'currency' => 'NZD',
104 'financial_type_id' => 1,
105 );
106 $getResult = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
107 $this->assertEquals(1, $getResult['count']);
108 }
109
110 public function testGetContributionPageByAmount() {
111 $createResult = $this->callAPISuccess($this->_entity, 'create', $this->params);
112 $this->id = $createResult['id'];
113 $getParams = array(
114 'amount' => '' . $this->testAmount, // 3456
115 'currency' => 'NZD',
116 'financial_type_id' => 1,
117 );
118 $getResult = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
119 $this->assertEquals(1, $getResult['count']);
120 }
121
122 public function testDeleteContributionPage() {
123 $createResult = $this->callAPISuccess($this->_entity, 'create', $this->params);
124 $deleteParams = array('id' => $createResult['id']);
125 $this->callAPIAndDocument($this->_entity, 'delete', $deleteParams, __FUNCTION__, __FILE__);
126 $checkDeleted = $this->callAPISuccess($this->_entity, 'get', array());
127 $this->assertEquals(0, $checkDeleted['count']);
128 }
129
130 public function testGetFieldsContributionPage() {
131 $result = $this->callAPISuccess($this->_entity, 'getfields', array('action' => 'create'));
132 $this->assertEquals(12, $result['values']['start_date']['type']);
133 }
134
135
136 /**
137 * Test form submission with basic price set.
138 */
139 public function testSubmit() {
140 $this->setUpContributionPage();
141 $priceFieldID = reset($this->_ids['price_field']);
142 $priceFieldValueID = reset($this->_ids['price_field_value']);
143 $submitParams = array(
144 'price_' . $priceFieldID => $priceFieldValueID,
145 'id' => (int) $this->_ids['contribution_page'],
146 'amount' => 10,
147 );
148
149 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
150 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page']));
151 //assert non-deductible amount
152 $this->assertEquals(5.00, $contribution['non_deductible_amount']);
153 }
154
155 /**
156 * Test form submission with billing first & last name where the contact does NOT
157 * otherwise have one.
158 */
159 public function testSubmitNewBillingNameData() {
160 $this->setUpContributionPage();
161 $contact = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => 'wonderwoman@amazon.com'));
162 $priceFieldID = reset($this->_ids['price_field']);
163 $priceFieldValueID = reset($this->_ids['price_field_value']);
164 $submitParams = array(
165 'price_' . $priceFieldID => $priceFieldValueID,
166 'id' => (int) $this->_ids['contribution_page'],
167 'amount' => 10,
168 'billing_first_name' => 'Wonder',
169 'billing_last_name' => 'Woman',
170 'contactID' => $contact['id'],
171 'email' => 'wonderwoman@amazon.com',
172 );
173
174 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
175 $contact = $this->callAPISuccess('Contact', 'get', array(
176 'id' => $contact['id'],
177 'return' => array(
178 'first_name',
179 'last_name',
180 'sort_name',
181 'display_name',
182 ),
183 ));
184 $this->assertEquals(array(
185 'first_name' => 'Wonder',
186 'last_name' => 'Woman',
187 'display_name' => 'Wonder Woman',
188 'sort_name' => 'Woman, Wonder',
189 'id' => $contact['id'],
190 'contact_id' => $contact['id'],
191 ), $contact['values'][$contact['id']]);
192
193 }
194
195 /**
196 * Test form submission with billing first & last name where the contact does
197 * otherwise have one and should not be overwritten.
198 */
199 public function testSubmitNewBillingNameDoNotOverwrite() {
200 $this->setUpContributionPage();
201 $contact = $this->callAPISuccess('Contact', 'create', array(
202 'contact_type' => 'Individual',
203 'email' => 'wonderwoman@amazon.com',
204 'first_name' => 'Super',
205 'last_name' => 'Boy',
206 ));
207 $priceFieldID = reset($this->_ids['price_field']);
208 $priceFieldValueID = reset($this->_ids['price_field_value']);
209 $submitParams = array(
210 'price_' . $priceFieldID => $priceFieldValueID,
211 'id' => (int) $this->_ids['contribution_page'],
212 'amount' => 10,
213 'billing_first_name' => 'Wonder',
214 'billing_last_name' => 'Woman',
215 'contactID' => $contact['id'],
216 'email' => 'wonderwoman@amazon.com',
217 );
218
219 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
220 $contact = $this->callAPISuccess('Contact', 'get', array(
221 'id' => $contact['id'],
222 'return' => array(
223 'first_name',
224 'last_name',
225 'sort_name',
226 'display_name',
227 ),
228 ));
229 $this->assertEquals(array(
230 'first_name' => 'Super',
231 'last_name' => 'Boy',
232 'display_name' => 'Super Boy',
233 'sort_name' => 'Boy, Super',
234 'id' => $contact['id'],
235 'contact_id' => $contact['id'],
236 ), $contact['values'][$contact['id']]);
237
238 }
239
240 /**
241 * Test process with instant payment when more than one configured for the page.
242 *
243 * CRM-16923
244 */
245 public function testSubmitRecurMultiProcessorInstantPayment() {
246 $this->setUpContributionPage();
247 $this->setupPaymentProcessor();
248 $paymentProcessor2ID = $this->paymentProcessorCreate(array(
249 'payment_processor_type_id' => 'Dummy',
250 'name' => 'processor 2',
251 'class_name' => 'Payment_Dummy',
252 'billing_mode' => 1,
253 ));
254 $dummyPP = Civi\Payment\System::singleton()->getById($paymentProcessor2ID);
255 $dummyPP->setDoDirectPaymentResult(array(
256 'payment_status_id' => 1,
257 'trxn_id' => 'create_first_success',
258 'fee_amount' => .85,
259 ));
260 $processor = $dummyPP->getPaymentProcessor();
261 $this->callAPISuccess('ContributionPage', 'create', array(
262 'id' => $this->_ids['contribution_page'],
263 'payment_processor' => array($paymentProcessor2ID, $this->_ids['payment_processor']),
264 ));
265
266 $priceFieldID = reset($this->_ids['price_field']);
267 $priceFieldValueID = reset($this->_ids['price_field_value']);
268 $submitParams = array(
269 'price_' . $priceFieldID => $priceFieldValueID,
270 'id' => (int) $this->_ids['contribution_page'],
271 'amount' => 10,
272 'is_recur' => 1,
273 'frequency_interval' => 1,
274 'frequency_unit' => 'month',
275 'payment_processor_id' => $paymentProcessor2ID,
276 );
277
278 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
279 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
280 'contribution_page_id' => $this->_ids['contribution_page'],
281 'contribution_status_id' => 1,
282 ));
283 $this->assertEquals('create_first_success', $contribution['trxn_id']);
284 $this->assertEquals(10, $contribution['total_amount']);
285 $this->assertEquals(.85, $contribution['fee_amount']);
286 $this->assertEquals(9.15, $contribution['net_amount']);
287 $this->_checkFinancialRecords(array(
288 'id' => $contribution['id'],
289 'total_amount' => $contribution['total_amount'],
290 'payment_instrument_id' => $processor['payment_instrument_id'],
291 ), 'online');
292 }
293
294 /**
295 * Test submit with a membership block in place.
296 */
297 public function testSubmitMembershipBlockNotSeparatePayment() {
298 $this->setUpMembershipContributionPage();
299 $submitParams = array(
300 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
301 'id' => (int) $this->_ids['contribution_page'],
302 'amount' => 10,
303 'billing_first_name' => 'Billy',
304 'billing_middle_name' => 'Goat',
305 'billing_last_name' => 'Gruff',
306 'selectMembership' => $this->_ids['membership_type'],
307
308 );
309
310 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
311 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page']));
312 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array('contribution_id' => $contribution['id']));
313 $this->callAPISuccessGetSingle('LineItem', array('contribution_id' => $contribution['id'], 'entity_id' => $membershipPayment['id']));
314 }
315
316 /**
317 * Test submit with a membership block in place.
318 */
319 public function testSubmitMembershipBlockNotSeparatePaymentWithEmail() {
320 $mut = new CiviMailUtils($this, TRUE);
321 $this->setUpMembershipContributionPage();
322 $this->addProfile('supporter_profile', $this->_ids['contribution_page']);
323
324 $submitParams = array(
325 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
326 'id' => (int) $this->_ids['contribution_page'],
327 'amount' => 10,
328 'billing_first_name' => 'Billy',
329 'billing_middle_name' => 'Goat',
330 'billing_last_name' => 'Gruff',
331 'selectMembership' => $this->_ids['membership_type'],
332 'email-Primary' => 'billy-goat@the-bridge.net',
333 'payment_processor_id' => $this->_paymentProcessor['id'],
334 'credit_card_number' => '4111111111111111',
335 'credit_card_type' => 'Visa',
336 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
337 'cvv2' => 123,
338 );
339
340 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
341 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page']));
342 $this->callAPISuccess('membership_payment', 'getsingle', array('contribution_id' => $contribution['id']));
343 $mut->checkMailLog(array(
344 'Membership Type: General',
345 ));
346 $mut->stop();
347 $mut->clearMessages();
348 }
349
350 /**
351 * Test submit with a membership block in place.
352 */
353 public function testSubmitMembershipBlockNotSeparatePaymentZeroDollarsWithEmail() {
354 $mut = new CiviMailUtils($this, TRUE);
355 $this->_ids['membership_type'] = array($this->membershipTypeCreate(array('minimum_fee' => 0)));
356 $this->setUpMembershipContributionPage();
357 $this->addProfile('supporter_profile', $this->_ids['contribution_page']);
358
359 $submitParams = array(
360 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
361 'id' => (int) $this->_ids['contribution_page'],
362 'amount' => 0,
363 'billing_first_name' => 'Billy',
364 'billing_middle_name' => 'Goat',
365 'billing_last_name' => 'Gruffier',
366 'selectMembership' => $this->_ids['membership_type'],
367 'email-Primary' => 'billy-goat@the-new-bridge.net',
368 );
369
370 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
371 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page']));
372 $this->callAPISuccess('membership_payment', 'getsingle', array('contribution_id' => $contribution['id']));
373 $mut->checkMailLog(array(
374 'Membership Type: General',
375 'Gruffier',
376 ),
377 array(
378 'Amount',
379 )
380 );
381 $mut->stop();
382 $mut->clearMessages(999);
383 }
384
385 /**
386 * Test submit with a membership block in place.
387 */
388 public function testSubmitMembershipBlockIsSeparatePayment() {
389 $this->setUpMembershipContributionPage(TRUE);
390 $this->_ids['membership_type'] = array($this->membershipTypeCreate(array('minimum_fee' => 2)));
391 $submitParams = array(
392 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
393 'id' => (int) $this->_ids['contribution_page'],
394 'amount' => 10,
395 'billing_first_name' => 'Billy',
396 'billing_middle_name' => 'Goat',
397 'billing_last_name' => 'Gruff',
398 'selectMembership' => $this->_ids['membership_type'],
399 );
400
401 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
402 $contributions = $this->callAPISuccess('contribution', 'get', array('contribution_page_id' => $this->_ids['contribution_page']));
403 $this->assertCount(2, $contributions['values']);
404 $this->callAPISuccessGetCount('LineItem', array(), 2);
405 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
406 $this->assertTrue(in_array($membershipPayment['contribution_id'], array_keys($contributions['values'])));
407 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
408 $this->assertEquals($membership['contact_id'], $contributions['values'][$membershipPayment['contribution_id']]['contact_id']);
409 }
410
411 /**
412 * Test submit with a membership block in place.
413 */
414 public function testSubmitMembershipBlockIsSeparatePaymentWithEmail() {
415 $mut = new CiviMailUtils($this, TRUE);
416 $this->setUpMembershipContributionPage(TRUE);
417 $this->addProfile('supporter_profile', $this->_ids['contribution_page']);
418
419 $submitParams = array(
420 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
421 'id' => (int) $this->_ids['contribution_page'],
422 'amount' => 10,
423 'billing_first_name' => 'Billy',
424 'billing_middle_name' => 'Goat',
425 'billing_last_name' => 'Gruff',
426 'selectMembership' => $this->_ids['membership_type'],
427 'email-Primary' => 'billy-goat@the-bridge.net',
428 'payment_processor_id' => $this->_paymentProcessor['id'],
429 'credit_card_number' => '4111111111111111',
430 'credit_card_type' => 'Visa',
431 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
432 'cvv2' => 123,
433 );
434
435 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
436 $contributions = $this->callAPISuccess('contribution', 'get', array('contribution_page_id' => $this->_ids['contribution_page']));
437 $this->assertCount(2, $contributions['values']);
438 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
439 $this->assertTrue(in_array($membershipPayment['contribution_id'], array_keys($contributions['values'])));
440 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
441 $this->assertEquals($membership['contact_id'], $contributions['values'][$membershipPayment['contribution_id']]['contact_id']);
442 // We should have two separate email messages, each with their own amount
443 // line and no total line.
444 $mut->checkAllMailLog(
445 array(
446 'Amount: $ 2.00',
447 'Amount: $ 10.00',
448 'Membership Fee',
449 ),
450 array(
451 'Total: $',
452 )
453 );
454 $mut->stop();
455 $mut->clearMessages(999);
456 }
457
458 /**
459 * Test submit with a membership block in place.
460 */
461 public function testSubmitMembershipBlockIsSeparatePaymentZeroDollarsPayLaterWithEmail() {
462 $mut = new CiviMailUtils($this, TRUE);
463 $this->_ids['membership_type'] = array($this->membershipTypeCreate(array('minimum_fee' => 0)));
464 $this->setUpMembershipContributionPage(TRUE);
465 $this->addProfile('supporter_profile', $this->_ids['contribution_page']);
466
467 $submitParams = array(
468 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
469 'id' => (int) $this->_ids['contribution_page'],
470 'amount' => 0,
471 'billing_first_name' => 'Billy',
472 'billing_middle_name' => 'Goat',
473 'billing_last_name' => 'Gruffalo',
474 'selectMembership' => $this->_ids['membership_type'],
475 'payment_processor_id' => 0,
476 'email-Primary' => 'gruffalo@the-bridge.net',
477 );
478
479 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
480 $contributions = $this->callAPISuccess('contribution', 'get', array('contribution_page_id' => $this->_ids['contribution_page']));
481 $this->assertCount(2, $contributions['values']);
482 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
483 $this->assertTrue(in_array($membershipPayment['contribution_id'], array_keys($contributions['values'])));
484 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
485 $this->assertEquals($membership['contact_id'], $contributions['values'][$membershipPayment['contribution_id']]['contact_id']);
486 $mut->checkMailLog(array(
487 'Gruffalo',
488 'General Membership: $ 0.00',
489 'Membership Fee',
490 ));
491 $mut->stop();
492 $mut->clearMessages();
493 }
494
495 /**
496 * Test submit with a membership block in place.
497 */
498 public function testSubmitMembershipBlockTwoTypesIsSeparatePayment() {
499 $this->_ids['membership_type'] = array($this->membershipTypeCreate(array('minimum_fee' => 6)));
500 $this->_ids['membership_type'][] = $this->membershipTypeCreate(array('name' => 'Student', 'minimum_fee' => 50));
501 $this->setUpMembershipContributionPage(TRUE);
502 $submitParams = array(
503 'price_' . $this->_ids['price_field'][0] => $this->_ids['price_field_value'][1],
504 'id' => (int) $this->_ids['contribution_page'],
505 'amount' => 10,
506 'billing_first_name' => 'Billy',
507 'billing_middle_name' => 'Goat',
508 'billing_last_name' => 'Gruff',
509 'selectMembership' => $this->_ids['membership_type'][1],
510 );
511
512 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
513 $contributions = $this->callAPISuccess('contribution', 'get', array('contribution_page_id' => $this->_ids['contribution_page']));
514 $this->assertCount(2, $contributions['values']);
515 $ids = array_keys($contributions['values']);
516 $this->assertEquals('10.00', $contributions['values'][$ids[0]]['total_amount']);
517 $this->assertEquals('50.00', $contributions['values'][$ids[1]]['total_amount']);
518 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
519 $this->assertArrayHasKey($membershipPayment['contribution_id'], $contributions['values']);
520 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
521 $this->assertEquals($membership['contact_id'], $contributions['values'][$membershipPayment['contribution_id']]['contact_id']);
522 }
523
524 /**
525 * Test submit with a membership block in place.
526 *
527 * We are expecting a separate payment for the membership vs the contribution.
528 */
529 public function testSubmitMembershipBlockIsSeparatePaymentPaymentProcessorNow() {
530 $this->setUpMembershipContributionPage(TRUE);
531 $processor = Civi\Payment\System::singleton()->getById($this->_paymentProcessor['id']);
532 $processor->setDoDirectPaymentResult(array('fee_amount' => .72));
533 $submitParams = array(
534 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
535 'id' => (int) $this->_ids['contribution_page'],
536 'amount' => 10,
537 'billing_first_name' => 'Billy',
538 'billing_middle_name' => 'Goat',
539 'billing_last_name' => 'Gruff',
540 'selectMembership' => $this->_ids['membership_type'],
541 'payment_processor_id' => $this->_paymentProcessor['id'],
542 'credit_card_number' => '4111111111111111',
543 'credit_card_type' => 'Visa',
544 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
545 'cvv2' => 123,
546 );
547
548 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
549 $contributions = $this->callAPISuccess('contribution', 'get', array(
550 'contribution_page_id' => $this->_ids['contribution_page'],
551 'contribution_status_id' => 1,
552 ));
553 $this->assertCount(2, $contributions['values']);
554 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
555 $this->assertTrue(in_array($membershipPayment['contribution_id'], array_keys($contributions['values'])));
556 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
557 $this->assertEquals($membership['contact_id'], $contributions['values'][$membershipPayment['contribution_id']]['contact_id']);
558 foreach ($contributions['values'] as $contribution) {
559 $this->assertEquals(.72, $contribution['fee_amount']);
560 $this->assertEquals($contribution['total_amount'] - .72, $contribution['net_amount']);
561 }
562 }
563
564 /**
565 * Test that when a transaction fails the pending contribution remains.
566 *
567 * An activity should also be created. CRM-16417.
568 */
569 public function testSubmitPaymentProcessorFailure() {
570 $this->setUpContributionPage();
571 $this->setupPaymentProcessor();
572 $this->createLoggedInUser();
573 $priceFieldID = reset($this->_ids['price_field']);
574 $priceFieldValueID = reset($this->_ids['price_field_value']);
575 $submitParams = array(
576 'price_' . $priceFieldID => $priceFieldValueID,
577 'id' => (int) $this->_ids['contribution_page'],
578 'amount' => 10,
579 'payment_processor_id' => 1,
580 'credit_card_number' => '4111111111111111',
581 'credit_card_type' => 'Visa',
582 'credit_card_exp_date' => array('M' => 9, 'Y' => 2008),
583 'cvv2' => 123,
584 );
585
586 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
587 $contribution = $this->callAPISuccessGetSingle('contribution', array(
588 'contribution_page_id' => $this->_ids['contribution_page'],
589 'contribution_status_id' => 2,
590 ));
591
592 $this->callAPISuccessGetSingle('activity', array(
593 'source_record_id' => $contribution['id'],
594 'activity_type_id' => 'Failed Payment',
595 ));
596
597 }
598
599 /**
600 * Test submit recurring membership with immediate confirmation (IATS style).
601 *
602 * - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate
603 * processor (IATS style - denoted by returning trxn_id)
604 * - the first creates a new membership, completed contribution, in progress recurring. Check these
605 * - create another - end date should be extended
606 */
607 public function testSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPayment() {
608 $this->params['is_recur'] = 1;
609 $this->params['recur_frequency_unit'] = 'month';
610 $this->setUpMembershipContributionPage();
611 $dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
612 $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_first_success'));
613 $processor = $dummyPP->getPaymentProcessor();
614
615 $submitParams = array(
616 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
617 'id' => (int) $this->_ids['contribution_page'],
618 'amount' => 10,
619 'billing_first_name' => 'Billy',
620 'billing_middle_name' => 'Goat',
621 'billing_last_name' => 'Gruff',
622 'email' => 'billy@goat.gruff',
623 'selectMembership' => $this->_ids['membership_type'],
624 'payment_processor_id' => 1,
625 'credit_card_number' => '4111111111111111',
626 'credit_card_type' => 'Visa',
627 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
628 'cvv2' => 123,
629 'is_recur' => 1,
630 'frequency_interval' => 1,
631 'frequency_unit' => 'month',
632 );
633
634 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
635 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
636 'contribution_page_id' => $this->_ids['contribution_page'],
637 'contribution_status_id' => 1,
638 ));
639 $this->assertEquals($processor['payment_instrument_id'], $contribution['payment_instrument_id']);
640
641 $this->assertEquals('create_first_success', $contribution['trxn_id']);
642 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
643 $this->assertEquals($membershipPayment['contribution_id'], $contribution['id']);
644 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
645 $this->assertEquals($membership['contact_id'], $contribution['contact_id']);
646 $this->assertEquals(1, $membership['status_id']);
647 $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $contribution['contribution_recur_id']));
648
649 $this->callAPISuccess('line_item', 'getsingle', array('contribution_id' => $contribution['id'], 'entity_id' => $membership['id']));
650 //renew it with processor setting completed - should extend membership
651 $submitParams['contact_id'] = $contribution['contact_id'];
652 $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_second_success'));
653 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
654 $this->callAPISuccess('contribution', 'getsingle', array(
655 'id' => array('NOT IN' => array($contribution['id'])),
656 'contribution_page_id' => $this->_ids['contribution_page'],
657 'contribution_status_id' => 1,
658 ));
659 $renewedMembership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
660 $this->assertEquals(date('Y-m-d', strtotime('+ 1 year', strtotime($membership['end_date']))), $renewedMembership['end_date']);
661 $recurringContribution = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $contribution['contribution_recur_id']));
662 $this->assertEquals($processor['payment_instrument_id'], $recurringContribution['payment_instrument_id']);
663 $this->assertEquals(5, $recurringContribution['contribution_status_id']);
664 }
665
666 /**
667 * Test submit recurring membership with immediate confirmation (IATS style).
668 *
669 * - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate
670 * processor (IATS style - denoted by returning trxn_id)
671 * - the first creates a new membership, completed contribution, in progress recurring. Check these
672 * - create another - end date should be extended
673 */
674 public function testSubmitMembershipPriceSetPaymentPaymentProcessorSeparatePaymentRecurInstantPayment() {
675
676 $this->setUpMembershipContributionPage(TRUE);
677 $dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
678 $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_first_success'));
679
680 $submitParams = array(
681 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
682 'id' => (int) $this->_ids['contribution_page'],
683 'amount' => 10,
684 'billing_first_name' => 'Billy',
685 'billing_middle_name' => 'Goat',
686 'billing_last_name' => 'Gruff',
687 'email' => 'billy@goat.gruff',
688 'selectMembership' => $this->_ids['membership_type'],
689 'payment_processor_id' => 1,
690 'credit_card_number' => '4111111111111111',
691 'credit_card_type' => 'Visa',
692 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
693 'cvv2' => 123,
694 'is_recur' => 1,
695 'auto_renew' => TRUE,
696 'frequency_interval' => 1,
697 'frequency_unit' => 'month',
698 );
699
700 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
701 $contribution = $this->callAPISuccess('contribution', 'get', array(
702 'contribution_page_id' => $this->_ids['contribution_page'],
703 'contribution_status_id' => 1,
704 ));
705
706 $this->assertEquals(2, $contribution['count']);
707 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
708 $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
709 $this->assertNotEmpty($contribution['values'][$membershipPayment['contribution_id']]['contribution_recur_id']);
710 $this->callAPISuccess('contribution_recur', 'getsingle', array());
711 }
712
713 /**
714 * Test submit recurring membership with delayed confirmation (Authorize.net style)
715 * - we process 2 membership transactions against with a recurring contribution against a contribution page with a delayed
716 * processor (Authorize.net style - denoted by NOT returning trxn_id)
717 * - the first creates a pending membership, pending contribution, penging recurring. Check these
718 * - complete the transaction
719 * - create another - end date should NOT be extended
720 */
721 public function testSubmitMembershipPriceSetPaymentPaymentProcessorRecurDelayed() {
722 $this->params['is_recur'] = 1;
723 $this->params['recur_frequency_unit'] = 'month';
724 $this->setUpMembershipContributionPage();
725 $dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
726 $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 2));
727 $this->membershipTypeCreate(array('name' => 'Student'));
728
729 // Add a contribution & a couple of memberships so the id will not be 1 & will differ from membership id.
730 // This saves us from 'accidental success'.
731 $this->contributionCreate(array('contact_id' => $this->contactIds[0]));
732 $this->contactMembershipCreate(array('contact_id' => $this->contactIds[0]));
733 $this->contactMembershipCreate(array('contact_id' => $this->contactIds[0], 'membership_type_id' => 'Student'));
734
735 $submitParams = array(
736 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
737 'id' => (int) $this->_ids['contribution_page'],
738 'amount' => 10,
739 'billing_first_name' => 'Billy',
740 'billing_middle_name' => 'Goat',
741 'billing_last_name' => 'Gruff',
742 'email' => 'billy@goat.gruff',
743 'selectMembership' => $this->_ids['membership_type'],
744 'payment_processor_id' => 1,
745 'credit_card_number' => '4111111111111111',
746 'credit_card_type' => 'Visa',
747 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
748 'cvv2' => 123,
749 'is_recur' => 1,
750 'frequency_interval' => 1,
751 'frequency_unit' => 'month',
752 );
753
754 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
755 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
756 'contribution_page_id' => $this->_ids['contribution_page'],
757 'contribution_status_id' => 2,
758 ));
759
760 $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
761 $this->assertEquals($membershipPayment['contribution_id'], $contribution['id']);
762 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
763 $this->assertEquals($membership['contact_id'], $contribution['contact_id']);
764 $this->assertEquals(5, $membership['status_id']);
765
766 $line = $this->callAPISuccess('line_item', 'getsingle', array('contribution_id' => $contribution['id']));
767 $this->assertEquals('civicrm_membership', $line['entity_table']);
768 $this->assertEquals($membership['id'], $line['entity_id']);
769
770 $this->callAPISuccess('contribution', 'completetransaction', array(
771 'id' => $contribution['id'],
772 'trxn_id' => 'ipn_called',
773 'payment_processor_id' => $this->_paymentProcessor['id'],
774 ));
775 $line = $this->callAPISuccess('line_item', 'getsingle', array('contribution_id' => $contribution['id']));
776 $this->assertEquals('civicrm_membership', $line['entity_table']);
777 $this->assertEquals($membership['id'], $line['entity_id']);
778
779 $membership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
780 //renew it with processor setting completed - should extend membership
781 $submitParams = array_merge($submitParams, array(
782 'contact_id' => $contribution['contact_id'],
783 'is_recur' => 1,
784 'frequency_interval' => 1,
785 'frequency_unit' => 'month',
786 )
787 );
788
789 $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 2));
790 $this->callAPISuccess('contribution_page', 'submit', $submitParams);
791 $newContribution = $this->callAPISuccess('contribution', 'getsingle', array(
792 'id' => array(
793 'NOT IN' => array($contribution['id']),
794 ),
795 'contribution_page_id' => $this->_ids['contribution_page'],
796 'contribution_status_id' => 2,
797 )
798 );
799 $line = $this->callAPISuccess('line_item', 'getsingle', array('contribution_id' => $newContribution['id']));
800 $this->assertEquals('civicrm_membership', $line['entity_table']);
801 $this->assertEquals($membership['id'], $line['entity_id']);
802
803 $renewedMembership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
804 //no renewal as the date hasn't changed
805 $this->assertEquals($membership['end_date'], $renewedMembership['end_date']);
806 $recurringContribution = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $newContribution['contribution_recur_id']));
807 $this->assertEquals(2, $recurringContribution['contribution_status_id']);
808 }
809
810 /**
811 * Set up membership contribution page.
812 * @param bool $isSeparatePayment
813 */
814 public function setUpMembershipContributionPage($isSeparatePayment = FALSE) {
815 $this->setUpMembershipBlockPriceSet();
816 $this->setupPaymentProcessor();
817 $this->setUpContributionPage();
818
819 $this->callAPISuccess('membership_block', 'create', array(
820 'entity_id' => $this->_ids['contribution_page'],
821 'entity_table' => 'civicrm_contribution_page',
822 'is_required' => TRUE,
823 'is_active' => TRUE,
824 'is_separate_payment' => $isSeparatePayment,
825 'membership_type_default' => $this->_ids['membership_type'],
826 ));
827 }
828
829 /**
830 * Set up pledge block.
831 */
832 public function setUpPledgeBlock() {
833 $params = array(
834 'entity_table' => 'civicrm_contribution_page',
835 'entity_id' => $this->_ids['contribution_page'],
836 'pledge_frequency_unit' => 'week',
837 'is_pledge_interval' => 0,
838 'pledge_start_date' => json_encode(array('calendar_date' => date('Ymd', strtotime("+1 month")))),
839 );
840 $pledgeBlock = CRM_Pledge_BAO_PledgeBlock::create($params);
841 $this->_ids['pledge_block_id'] = $pledgeBlock->id;
842 }
843
844 /**
845 * The default data set does not include a complete default membership price set - not quite sure why.
846 *
847 * This function ensures it exists & populates $this->_ids with it's data
848 */
849 public function setUpMembershipBlockPriceSet() {
850 $this->_ids['price_set'][] = $this->callAPISuccess('price_set', 'getvalue', array(
851 'name' => 'default_membership_type_amount',
852 'return' => 'id',
853 ));
854 if (empty($this->_ids['membership_type'])) {
855 $this->_ids['membership_type'] = array($this->membershipTypeCreate(array('minimum_fee' => 2)));
856 }
857 $priceField = $this->callAPISuccess('price_field', 'create', array(
858 'price_set_id' => reset($this->_ids['price_set']),
859 'name' => 'membership_amount',
860 'label' => 'Membership Amount',
861 'html_type' => 'Radio',
862 'sequential' => 1,
863 ));
864 $this->_ids['price_field'][] = $priceField['id'];
865
866 foreach ($this->_ids['membership_type'] as $membershipTypeID) {
867 $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
868 'name' => 'membership_amount',
869 'label' => 'Membership Amount',
870 'amount' => 1,
871 'financial_type_id' => 'Donation',
872 'format.only_id' => TRUE,
873 'membership_type_id' => $membershipTypeID,
874 'price_field_id' => $priceField['id'],
875 ));
876 $this->_ids['price_field_value'][] = $priceFieldValue;
877 }
878 }
879
880 /**
881 * Add text field other amount to the price set.
882 */
883 public function addOtherAmountFieldToMembershipPriceSet() {
884 $this->_ids['price_field']['other_amount'] = $this->callAPISuccess('price_field', 'create', array(
885 'price_set_id' => reset($this->_ids['price_set']),
886 'name' => 'other_amount',
887 'label' => 'Other Amount',
888 'html_type' => 'Text',
889 'format.only_id' => TRUE,
890 'sequential' => 1,
891 ));
892 $this->_ids['price_field_value']['other_amount'] = $this->callAPISuccess('price_field_value', 'create', array(
893 'financial_type_id' => 'Donation',
894 'format.only_id' => TRUE,
895 'label' => 'Other Amount',
896 'amount' => 1,
897 'price_field_id' => $this->_ids['price_field']['other_amount'],
898 ));
899 }
900
901 /**
902 * Help function to set up contribution page with some defaults.
903 */
904 public function setUpContributionPage() {
905 $contributionPageResult = $this->callAPISuccess($this->_entity, 'create', $this->params);
906 if (empty($this->_ids['price_set'])) {
907 $priceSet = $this->callAPISuccess('price_set', 'create', $this->_priceSetParams);
908 $this->_ids['price_set'][] = $priceSet['id'];
909 }
910 $priceSetID = reset($this->_ids['price_set']);
911 CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPageResult['id'], $priceSetID);
912
913 if (empty($this->_ids['price_field'])) {
914 $priceField = $this->callAPISuccess('price_field', 'create', array(
915 'price_set_id' => $priceSetID,
916 'label' => 'Goat Breed',
917 'html_type' => 'Radio',
918 ));
919 $this->_ids['price_field'] = array($priceField['id']);
920 }
921 if (empty($this->_ids['price_field_value'])) {
922 $this->callAPISuccess('price_field_value', 'create', array(
923 'price_set_id' => $priceSetID,
924 'price_field_id' => $priceField['id'],
925 'label' => 'Long Haired Goat',
926 'financial_type_id' => 'Donation',
927 'amount' => 20,
928 'financial_type_id' => 'Donation',
929 'non_deductible_amount' => 15,
930 )
931 );
932 $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
933 'price_set_id' => $priceSetID,
934 'price_field_id' => $priceField['id'],
935 'label' => 'Shoe-eating Goat',
936 'financial_type_id' => 'Donation',
937 'amount' => 10,
938 'financial_type_id' => 'Donation',
939 'non_deductible_amount' => 5,
940 )
941 );
942 $this->_ids['price_field_value'] = array($priceFieldValue['id']);
943 }
944 $this->_ids['contribution_page'] = $contributionPageResult['id'];
945 }
946
947 public static function setUpBeforeClass() {
948 // put stuff here that should happen before all tests in this unit
949 }
950
951 public static function tearDownAfterClass() {
952 $tablesToTruncate = array(
953 'civicrm_contact',
954 'civicrm_financial_type',
955 'civicrm_contribution',
956 'civicrm_contribution_page',
957 );
958 $unitTest = new CiviUnitTestCase();
959 $unitTest->quickCleanup($tablesToTruncate);
960 }
961
962 /**
963 * Create a payment processor instance.
964 */
965 protected function setupPaymentProcessor() {
966 $this->params['payment_processor_id'] = $this->_ids['payment_processor'] = $this->paymentProcessorCreate(array(
967 'payment_processor_type_id' => 'Dummy',
968 'class_name' => 'Payment_Dummy',
969 'billing_mode' => 1,
970 ));
971 $this->_paymentProcessor = $this->callAPISuccess('payment_processor', 'getsingle', array('id' => $this->params['payment_processor_id']));
972 }
973
974 /**
975 * Test submit recurring pledge.
976 *
977 * - we process 1 pledge with a future start date. A recur contribution and the pledge should be created with first payment date in the future.
978 */
979 public function testSubmitPledgePaymentPaymentProcessorRecurFuturePayment() {
980 $this->params['adjust_recur_start_date'] = TRUE;
981 $this->params['is_pay_later'] = FALSE;
982 $this->setUpContributionPage();
983 $this->setUpPledgeBlock();
984 $this->setupPaymentProcessor();
985 $dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
986 $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_first_success'));
987
988 $submitParams = array(
989 'id' => (int) $this->_ids['contribution_page'],
990 'amount' => 100,
991 'billing_first_name' => 'Billy',
992 'billing_middle_name' => 'Goat',
993 'billing_last_name' => 'Gruff',
994 'email' => 'billy@goat.gruff',
995 'payment_processor_id' => 1,
996 'credit_card_number' => '4111111111111111',
997 'credit_card_type' => 'Visa',
998 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
999 'cvv2' => 123,
1000 'pledge_frequency_interval' => 1,
1001 'pledge_frequency_unit' => 'week',
1002 'pledge_installments' => 3,
1003 'is_pledge' => TRUE,
1004 'pledge_block_id' => (int) $this->_ids['pledge_block_id'],
1005 );
1006
1007 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
1008
1009 // Check if contribution created.
1010 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
1011 'contribution_page_id' => $this->_ids['contribution_page'],
1012 'contribution_status_id' => 'Completed', // Will be pending when actual payment processor is used (dummy processor does not support future payments).
1013 ));
1014
1015 $this->assertEquals('create_first_success', $contribution['trxn_id']);
1016
1017 // Check if pledge created.
1018 $pledge = $this->callAPISuccess('pledge', 'getsingle', array());
1019 $this->assertEquals(date('Ymd', strtotime($pledge['pledge_start_date'])), date('Ymd', strtotime("+1 month")));
1020 $this->assertEquals($pledge['pledge_amount'], 300.00);
1021
1022 // Check if pledge payments created.
1023 $params = array(
1024 'pledge_id' => $pledge['id'],
1025 );
1026 $pledgePayment = $this->callAPISuccess('pledge_payment', 'get', $params);
1027 $this->assertEquals($pledgePayment['count'], 3);
1028 $this->assertEquals(date('Ymd', strtotime($pledgePayment['values'][1]['scheduled_date'])), date('Ymd', strtotime("+1 month")));
1029 $this->assertEquals($pledgePayment['values'][1]['scheduled_amount'], 100.00);
1030 $this->assertEquals($pledgePayment['values'][1]['status_id'], 1); // Will be pending when actual payment processor is used (dummy processor does not support future payments).
1031
1032 // Check contribution recur record.
1033 $recur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $contribution['contribution_recur_id']));
1034 $this->assertEquals(date('Ymd', strtotime($recur['start_date'])), date('Ymd', strtotime("+1 month")));
1035 $this->assertEquals($recur['amount'], 100.00);
1036 $this->assertEquals($recur['contribution_status_id'], 5); // In progress status.
1037 }
1038
1039 /**
1040 * Test submit pledge payment.
1041 *
1042 * - test submitting a pledge payment using contribution form.
1043 */
1044 public function testSubmitPledgePayment() {
1045 $this->testSubmitPledgePaymentPaymentProcessorRecurFuturePayment();
1046 $pledge = $this->callAPISuccess('pledge', 'getsingle', array());
1047 $params = array(
1048 'pledge_id' => $pledge['id'],
1049 );
1050 $submitParams = array(
1051 'id' => (int) $pledge['pledge_contribution_page_id'],
1052 'pledge_amount' => array(2 => 1),
1053 'billing_first_name' => 'Billy',
1054 'billing_middle_name' => 'Goat',
1055 'billing_last_name' => 'Gruff',
1056 'email' => 'billy@goat.gruff',
1057 'payment_processor_id' => 1,
1058 'credit_card_number' => '4111111111111111',
1059 'credit_card_type' => 'Visa',
1060 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
1061 'cvv2' => 123,
1062 'pledge_id' => $pledge['id'],
1063 'cid' => $pledge['contact_id'],
1064 'contact_id' => $pledge['contact_id'],
1065 'amount' => 100.00,
1066 'is_pledge' => TRUE,
1067 'pledge_block_id' => $this->_ids['pledge_block_id'],
1068 );
1069 $pledgePayment = $this->callAPISuccess('pledge_payment', 'get', $params);
1070 $this->assertEquals($pledgePayment['values'][2]['status_id'], 2);
1071
1072 $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
1073
1074 // Check if contribution created.
1075 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
1076 'contribution_page_id' => $pledge['pledge_contribution_page_id'],
1077 'contribution_status_id' => 'Completed',
1078 'contact_id' => $pledge['contact_id'],
1079 'contribution_recur_id' => array('IS NULL' => 1),
1080 ));
1081
1082 $this->assertEquals(100.00, $contribution['total_amount']);
1083 $pledgePayment = $this->callAPISuccess('pledge_payment', 'get', $params);
1084 $this->assertEquals($pledgePayment['values'][2]['status_id'], 1, "This pledge payment should have been completed");
1085 $this->assertEquals($pledgePayment['values'][2]['contribution_id'], $contribution['id']);
1086 }
1087
1088 }