3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
13 * Test class for Pledge API - civicrm_pledge_*
15 * @package CiviCRM_APIv3
18 class api_v3_PledgeTest
extends CiviUnitTestCase
{
20 protected $_individualId;
24 protected $scheduled_date;
27 * @throws \CRM_Core_Exception
29 public function setUp() {
30 $this->_apiversion
= 3;
32 $this->quickCleanup(['civicrm_pledge', 'civicrm_pledge_payment']);
33 //need to set scheduled payment in advance we are running test @ midnight & it becomes unexpectedly overdue
34 //due to timezone issues
35 $this->scheduled_date
= date('Ymd', mktime(0, 0, 0, date("m"), date("d") +
2, date("y")));
36 $this->_entity
= 'Pledge';
37 $this->_individualId
= $this->individualCreate();
39 'contact_id' => $this->_individualId
,
40 'pledge_create_date' => date('Ymd'),
41 'start_date' => date('Ymd'),
42 'scheduled_date' => $this->scheduled_date
,
44 'pledge_status_id' => '2',
45 'pledge_financial_type_id' => '1',
46 'pledge_original_installment_amount' => 20,
47 'frequency_interval' => 5,
48 'frequency_unit' => 'year',
49 'frequency_day' => 15,
55 public function tearDown() {
56 $this->contactDelete($this->_individualId
);
60 * Check with complete array + custom field.
62 * Note that the test is written on purpose without any
63 * variables specific to participant so it can be replicated into other entities
64 * and / or moved to the automated test suite
66 public function testCreateWithCustom() {
67 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
69 $params = $this->_params
;
70 $params['custom_' . $ids['custom_field_id']] = "custom string";
72 $result = $this->callAPISuccess($this->_entity
, 'create', $params);
73 $this->assertAPISuccess($result, " testCreateWithCustom ");
74 $this->assertAPISuccess($result);
75 $getParams = ['id' => $result['id'], 'return.custom_' . $ids['custom_field_id'] => 1];
76 $check = $this->callAPISuccess($this->_entity
, 'get', $getParams);
77 $this->callAPISuccess('pledge', 'delete', ['id' => $check['id']]);
78 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
80 $this->customFieldDelete($ids['custom_field_id']);
81 $this->customGroupDelete($ids['custom_group_id']);
85 * Test getfields function for pledge.
87 public function testGetfieldsPledge() {
88 $result = $this->callAPISuccess('pledge', 'getfields', ['action' => 'get']);
89 $this->assertEquals(1, $result['values']['next_pay_date']['api.return']);
93 * Test get pledge api.
95 public function testGetPledge() {
97 $this->_pledge
= $this->callAPISuccess('pledge', 'create', $this->_params
);
99 'pledge_id' => $this->_pledge
['id'],
101 $result = $this->callAPIAndDocument('pledge', 'get', $params, __FUNCTION__
, __FILE__
);
102 $pledge = $result['values'][$this->_pledge
['id']];
103 $this->assertEquals($this->_individualId
, $pledge['contact_id']);
104 $this->assertEquals($this->_pledge
['id'], $pledge['pledge_id']);
105 $this->assertEquals(date('Y-m-d') . ' 00:00:00', $pledge['pledge_create_date']);
106 $this->assertEquals(100.00, $pledge['pledge_amount']);
107 $this->assertEquals('Pending Label**', $pledge['pledge_status']);
108 $this->assertEquals(5, $pledge['pledge_frequency_interval']);
109 $this->assertEquals('year', $pledge['pledge_frequency_unit']);
110 $this->assertEquals(date('Y-m-d', strtotime($this->scheduled_date
)) . ' 00:00:00', $pledge['pledge_next_pay_date']);
111 $this->assertEquals($pledge['pledge_next_pay_amount'], 20.00);
114 'pledge_id' => $this->_pledge
['id'],
116 $pledge = $this->callAPISuccess('pledge', 'delete', $params2);
120 * Test 'return.pledge_financial_type' => 1 works.
122 public function testGetPledgeWithReturn() {
124 $this->_pledge
= $this->callAPISuccess('pledge', 'create', $this->_params
);
126 'pledge_id' => $this->_pledge
['id'],
127 'return.pledge_financial_type' => 1,
129 $result = $this->callAPISuccess('pledge', 'get', $params);
130 $pledge = $result['values'][$this->_pledge
['id']];
131 $this->callAPISuccess('pledge', 'delete', $pledge);
132 $this->assertEquals('Donation', $pledge['pledge_financial_type']);
136 * Test 'return.pledge_contribution_type' => 1 works.
138 * This is for legacy compatibility
140 public function testGetPledgeWithReturnLegacy() {
142 $this->_pledge
= $this->callAPISuccess('pledge', 'create', $this->_params
);
144 'pledge_id' => $this->_pledge
['id'],
145 'return.pledge_financial_type' => 1,
147 $result = $this->callAPISuccess('pledge', 'get', $params);
148 $pledge = $result['values'][$this->_pledge
['id']];
149 $this->callAPISuccess('pledge', 'delete', $pledge);
150 $this->assertEquals('Donation', $pledge['pledge_financial_type']);
154 * Test date legacy date filters like pledge_start_date_high.
156 public function testPledgeGetReturnFilters() {
157 $this->callAPISuccess('pledge', 'create', $this->_params
);
160 'scheduled_date' => 'first saturday of march last year',
161 'start_date' => 'first saturday of march last year',
163 $oldPledge = $this->callAPISuccess('pledge', 'create', array_merge($this->_params
, $overdueParams));
165 $pledgeGetParams = [];
166 $allPledges = $this->callAPISuccess('pledge', 'getcount', $pledgeGetParams);
168 $this->assertEquals(2, $allPledges, 'Check we have 2 pledges to place with in line ' . __LINE__
);
169 $pledgeGetParams['pledge_start_date_high'] = date('YmdHis', strtotime('2 days ago'));
170 $earlyPledge = $this->callAPIAndDocument('pledge', 'get', $pledgeGetParams, __FUNCTION__
, __FILE__
, "demonstrates high date filter", "GetFilterHighDate");
171 $this->assertEquals(1, $earlyPledge['count'], ' check only one returned with start date filter in line ' . __LINE__
);
172 $this->assertEquals($oldPledge['id'], $earlyPledge['id'], ' check correct pledge returned ' . __LINE__
);
176 * Create 2 pledges - see if we can get by status id.
178 public function testGetOverduePledge() {
180 'scheduled_date' => 'first saturday of march last year',
181 'start_date' => 'first saturday of march last year',
183 $this->_pledge
= $this->callAPISuccess('pledge', 'create', array_merge($this->_params
, $overdueParams));
185 $result = $this->callAPISuccess('pledge', 'get', ['status_id' => 'Overdue']);
186 $emptyResult = $this->callAPISuccess('pledge', 'get', [
187 'pledge_status_id' => '1',
189 $pledge = $result['values'][$this->_pledge
['id']];
190 $this->callAPISuccess('pledge', 'delete', $pledge);
191 $this->assertEquals(1, $result['count']);
192 $this->assertEquals(0, $emptyResult['count']);
196 * Test pledge_status option group
198 public function testOptionGroupForPledgeStatus() {
199 $pledgeOg = $this->callAPISuccess('OptionGroup', 'get', [
200 'name' => "pledge_status",
202 $this->assertEquals(1, $pledgeOg['count']);
204 $pledgeOv = $this->callAPISuccess('OptionValue', 'get', [
206 'option_group_id' => "pledge_status",
208 $this->assertEquals(5, $pledgeOv['count']);
209 $pledgeStatus = CRM_Utils_Array
::collect('name', $pledgeOv['values']);
210 $expected = ['Completed', 'Pending', 'Cancelled', 'In Progress', 'Overdue'];
211 $this->assertEquals($expected, $pledgeStatus);
215 * Create 2 pledges - see if we can get by status id.
217 public function testSortParamPledge() {
218 $pledge1 = $this->callAPISuccess('pledge', 'create', $this->_params
);
220 'scheduled_date' => 'first saturday of march last year',
221 'start_date' => 'first saturday of march last year',
222 'create_date' => 'first saturday of march last year',
224 $pledge2 = $this->callAPISuccess('pledge', 'create', array_merge($this->_params
, $overdueParams));
226 'pledge_is_test' => 0,
229 $result = $this->callAPISuccess('pledge', 'get', $params);
231 $resultSortedAsc = $this->callAPISuccess('pledge', 'get', [
233 'sort' => 'start_date ASC',
235 $resultSortedDesc = $this->callAPISuccess('pledge', 'get', [
237 'sort' => 'start_date DESC',
240 $this->assertEquals($pledge1['id'], $result['id'], 'pledge get gets first created pledge in line ' . __LINE__
);
241 $this->assertEquals($pledge2['id'], $resultSortedAsc['id'], 'Ascending pledge sort works');
242 $this->assertEquals($pledge1['id'], $resultSortedDesc['id'], 'Decending pledge sort works');
243 $this->callAPISuccess('pledge', 'delete', ['id' => $pledge1['id']]);
244 $this->callAPISuccess('pledge', 'delete', ['id' => $pledge2['id']]);
247 public function testCreatePledge() {
249 $result = $this->callAPIAndDocument('pledge', 'create', $this->_params
, __FUNCTION__
, __FILE__
);
250 $this->assertEquals($result['values'][0]['amount'], 100.00);
251 $this->assertEquals($result['values'][0]['installments'], 5);
252 $this->assertEquals($result['values'][0]['frequency_unit'], 'year');
253 $this->assertEquals($result['values'][0]['frequency_interval'], 5);
254 $this->assertEquals($result['values'][0]['frequency_day'], 15);
255 $this->assertEquals($result['values'][0]['original_installment_amount'], 20);
256 $this->assertEquals($result['values'][0]['status_id'], 2);
257 $this->assertEquals($result['values'][0]['create_date'], date('Ymd') . '000000');
258 $this->assertEquals($result['values'][0]['start_date'], date('Ymd') . '000000');
259 $this->assertAPISuccess($result);
260 $payments = $this->callAPISuccess('PledgePayment', 'Get', ['pledge_id' => $result['id'], 'sequential' => 1]);
261 $this->assertAPISuccess($payments);
262 $this->assertEquals($payments['count'], 5);
263 $shouldBeDate = CRM_Utils_Date
::format(CRM_Utils_Date
::intervalAdd('year', 5 * 4, $this->scheduled_date
), "-");
264 $this->assertEquals(substr($shouldBeDate, 0, 10), substr($payments['values'][4]['scheduled_date'], 0, 10));
266 $pledgeID = ['id' => $result['id']];
267 $pledge = $this->callAPISuccess('pledge', 'delete', $pledgeID);
271 * Test that pledge with weekly schedule calculates dates correctly.
273 public function testCreatePledgeWeeklySchedule() {
275 'scheduled_date' => '20110510',
276 'frequency_unit' => 'week',
277 'frequency_day' => 3,
278 'frequency_interval' => 2,
280 $params = array_merge($this->_params
, $params);
281 $pledge = $this->callAPISuccess('Pledge', 'Create', $params);
282 //ensure that correct number of payments created & last payment has the right date
283 $payments = $this->callAPISuccess('PledgePayment', 'Get', [
284 'pledge_id' => $pledge['id'],
287 $this->assertEquals($payments['count'], 5);
288 $this->assertEquals('2011-07-06 00:00:00', $payments['values'][4]['scheduled_date']);
290 $this->callAPISuccess('pledge', 'delete', ['pledge_id' => $pledge['id']]);
294 * Test that pledge with weekly schedule calculates dates correctly.
296 public function testCreatePledgeMontlySchedule() {
298 'scheduled_date' => '20110510',
299 'frequency_unit' => 'Month',
300 'frequency_day' => 3,
301 'frequency_interval' => 2,
303 $params = array_merge($this->_params
, $params);
304 $apiResult = $this->callAPISuccess('pledge', 'create', $params);
308 * Test creation of pledge with only one payment.
310 * Pledge status id left empty as it is not a required field
311 * http://issues.civicrm.org/jira/browse/CRM-8551
313 public function testCreatePledgeSinglePayment() {
315 'scheduled_date' => '20110510',
316 'frequency_unit' => 'week',
317 'frequency_day' => 3,
318 'frequency_interval' => 2,
322 $params = array_merge($this->_params
, $params);
323 unset($params['pledge_status_id']);
324 $pledge = $this->callAPISuccess('Pledge', 'Create', $params);
325 //ensure that correct number of payments created & last payment has the right date
326 $payments = $this->callAPISuccess('PledgePayment', 'Get', [
327 'pledge_id' => $pledge['id'],
330 $this->assertEquals(1, $payments['count']);
331 $this->assertEquals(2, $payments['values'][0]['status_id']);
332 $pledgeID = ['id' => $pledge['id']];
333 $pledge = $this->callAPISuccess('pledge', 'delete', $pledgeID);
337 * Test that using original_installment_amount rather than pledge_original_installment_amount works.
339 * Pledge field behaviour is a bit random & so pledge has come to try to handle both unique & non -unique fields.
341 public function testCreatePledgeWithNonUnique() {
342 $params = $this->_params
;
343 $params['original_installment_amount'] = $params['pledge_original_installment_amount'];
345 unset($params['pledge_original_installment_amount']);
346 $result = $this->callAPISuccess('pledge', 'create', $params);
347 $pledgeDetails = $this->callAPISuccess('Pledge', 'Get', ['id' => $result['id'], 'sequential' => 1]);
348 $pledge = $pledgeDetails['values'][0];
349 $this->assertEquals(100.00, $pledge['pledge_amount']);
350 $this->assertEquals('year', $pledge['pledge_frequency_unit']);
351 $this->assertEquals(5, $pledge['pledge_frequency_interval']);
352 $this->assertEquals(20, $pledge['pledge_next_pay_amount']);
354 $pledgeID = ['id' => $result['id']];
355 $pledge = $this->callAPISuccess('pledge', 'delete', $pledgeID);
359 * Test cancelling a pledge.
361 public function testCreateCancelPledge() {
363 $result = $this->callAPISuccess('pledge', 'create', $this->_params
);
364 $this->assertEquals(2, $result['values'][0]['status_id']);
367 'id' => $result['id'],
368 'pledge_status_id' => 3,
370 $result = $this->callAPISuccess('pledge', 'create', $cancelParams);
371 $this->assertEquals(3, $result['values'][0]['status_id']);
372 $pledgeID = ['id' => $result['id']];
373 $this->callAPISuccess('pledge', 'delete', $pledgeID);
377 * Test that status is set to pending.
379 public function testCreatePledgeNoStatus() {
381 $params = $this->_params
;
382 unset($params['status_id']);
383 unset($params['pledge_status_id']);
384 $result = $this->callAPISuccess('pledge', 'create', $params);
385 $this->assertAPISuccess($result);
386 $this->assertEquals(2, $result['values'][0]['status_id']);
387 $pledgeID = ['pledge_id' => $result['id']];
388 $pledge = $this->callAPISuccess('pledge', 'delete', $pledgeID);
394 public function testCreateUpdatePledge() {
395 // we test 'sequential' param here too
396 $pledgeID = $this->pledgeCreate(['contact_id' => $this->_individualId
]);
401 $original = $this->callAPISuccess('pledge', 'get', $old_params);
402 //Make sure it came back
403 $this->assertEquals($original['values'][0]['pledge_id'], $pledgeID);
404 //set up list of old params, verify
405 $old_contact_id = $original['values'][0]['contact_id'];
406 $old_frequency_unit = $original['values'][0]['pledge_frequency_unit'];
407 $old_frequency_interval = $original['values'][0]['pledge_frequency_interval'];
408 $old_status_id = $original['values'][0]['pledge_status'];
410 //check against values in CiviUnitTestCase::createPledge()
411 $this->assertEquals($old_contact_id, $this->_individualId
);
412 $this->assertEquals($old_frequency_unit, 'year');
413 $this->assertEquals($old_frequency_interval, 5);
414 $this->assertEquals($old_status_id, 'Pending Label**');
417 'contact_id' => $this->_individualId
,
418 'pledge_status_id' => 3,
420 'financial_type_id' => 1,
421 'start_date' => date('Ymd'),
422 'installments' => 10,
425 $pledge = $this->callAPISuccess('pledge', 'create', $params);
427 'id' => $pledge['id'],
429 $pledge = $this->callAPISuccess('pledge', 'get', $new_params);
430 $this->assertEquals($pledge['values'][$pledgeID]['contact_id'], $this->_individualId
);
431 $this->assertEquals($pledge['values'][$pledgeID]['pledge_status'], 'Cancelled');
432 $pledge = $this->callAPISuccess('pledge', 'delete', $new_params);
436 * Here we ensure we are maintaining our 'contract' & supporting previously working syntax.
438 * ie contribution_type_id.
440 * We test 'sequential' param here too.
442 public function testCreateUpdatePledgeLegacy() {
443 $pledgeID = $this->pledgeCreate(['contact_id' => $this->_individualId
]);
448 $original = $this->callAPISuccess('pledge', 'get', $old_params);
449 // Make sure it came back.
450 $this->assertEquals($original['values'][0]['pledge_id'], $pledgeID);
451 // Set up list of old params, verify.
452 $old_contact_id = $original['values'][0]['contact_id'];
453 $old_frequency_unit = $original['values'][0]['pledge_frequency_unit'];
454 $old_frequency_interval = $original['values'][0]['pledge_frequency_interval'];
455 $old_status_id = $original['values'][0]['pledge_status'];
457 // Check against values in CiviUnitTestCase::createPledge().
458 $this->assertEquals($old_contact_id, $this->_individualId
);
459 $this->assertEquals($old_frequency_unit, 'year');
460 $this->assertEquals($old_frequency_interval, 5);
461 $this->assertEquals($old_status_id, 'Pending Label**');
464 'contact_id' => $this->_individualId
,
465 'pledge_status_id' => 3,
467 'contribution_type_id' => 1,
468 'start_date' => date('Ymd'),
469 'installments' => 10,
472 $pledge = $this->callAPISuccess('pledge', 'create', $params);
474 'id' => $pledge['id'],
476 $pledge = $this->callAPISuccess('pledge', 'get', $new_params);
477 $this->assertEquals($pledge['values'][$pledgeID]['contact_id'], $this->_individualId
);
478 $this->assertEquals($pledge['values'][$pledgeID]['pledge_status'], 'Cancelled');
479 $this->callAPISuccess('pledge', 'delete', $new_params);
483 * Failure test for delete without id.
485 public function testDeleteEmptyParamsPledge() {
486 $this->callAPIFailure('pledge', 'delete', [], 'Mandatory key(s) missing from params array: id');
490 * Failure test for invalid pledge id.
492 public function testDeleteWrongParamPledge() {
494 'pledge_source' => 'SSF',
496 $this->callAPIFailure('pledge', 'delete', $params, 'Mandatory key(s) missing from params array: id');
500 * Legacy support for pledge_id.
502 public function testDeletePledge() {
504 $pledgeID = $this->pledgeCreate(['contact_id' => $this->_individualId
]);
506 'pledge_id' => $pledgeID,
508 $this->callAPIAndDocument('pledge', 'delete', $params, __FUNCTION__
, __FILE__
);
512 * Standard is to accept id.
514 public function testDeletePledgeUseID() {
516 $pledgeID = $this->pledgeCreate(['contact_id' => $this->_individualId
]);
520 $this->callAPIAndDocument('pledge', 'delete', $params, __FUNCTION__
, __FILE__
);
524 * Test to make sure empty get returns nothing.
526 * Note that the function gives incorrect results if no pledges exist as it does a
527 * contact search instead - test only checks that the get finds the one existing
529 public function testGetEmpty() {
530 $this->callAPISuccess('pledge', 'create', $this->_params
);
531 $result = $this->callAPISuccess('pledge', 'get', []);
532 $this->assertAPISuccess($result, "This test is failing because it's acting like a contact get when no params set. Not sure the fix");
533 $this->assertEquals(1, $result['count']);
534 $pledgeID = ['id' => $result['id']];
535 $this->callAPISuccess('pledge', 'delete', $pledgeID);