3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2020 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * Test CRM_Member_Form_Membership functions.
34 class CRM_Member_Form_MembershipRenewalTest
extends CiviUnitTestCase
{
36 protected $_individualId;
37 protected $_contribution;
38 protected $_financialTypeId = 1;
39 protected $_entity = 'Membership';
41 protected $_paymentProcessorID;
44 * Membership type ID for annual fixed membership.
48 protected $membershipTypeAnnualFixedID;
51 * Parameters to create payment processor.
55 protected $_processorParams = [];
58 * ID of created membership.
62 protected $_membershipID;
65 * Payment instrument mapping.
69 protected $paymentInstruments = [];
78 * Test setup for every test.
80 * Connect to the database, truncate the tables that will be used
81 * and redirect stdin to a temporary file.
83 public function setUp() {
86 $this->_individualId
= $this->individualCreate();
87 $this->_paymentProcessorID
= $this->processorCreate();
89 $this->loadXMLDataSet(dirname(__FILE__
) . '/dataset/data.xml');
90 $membershipTypeAnnualFixed = $this->callAPISuccess('membership_type', 'create', [
92 'name' => "AnnualFixed",
93 'member_of_contact_id' => 23,
94 'duration_unit' => "year",
95 'duration_interval' => 1,
96 'period_type' => "fixed",
97 'fixed_period_start_day' => "101",
98 'fixed_period_rollover_day' => "1231",
99 'relationship_type_id' => 20,
100 'financial_type_id' => 2,
102 $this->membershipTypeAnnualFixedID
= $membershipTypeAnnualFixed['id'];
103 $membership = $this->callAPISuccess('Membership', 'create', [
104 'contact_id' => $this->_individualId
,
105 'membership_type_id' => $this->membershipTypeAnnualFixedID
,
107 $this->_membershipID
= $membership['id'];
109 $instruments = $this->callAPISuccess('contribution', 'getoptions', ['field' => 'payment_instrument_id']);
110 $this->paymentInstruments
= $instruments['values'];
114 * Clean up after each test.
116 public function tearDown() {
117 $this->quickCleanUpFinancialEntities();
120 'civicrm_relationship',
121 'civicrm_membership_type',
122 'civicrm_membership',
127 foreach ([17, 18, 23, 32] as $contactID) {
128 $this->callAPISuccess('contact', 'delete', ['id' => $contactID, 'skip_undelete' => TRUE]);
130 $this->callAPISuccess('relationship_type', 'delete', ['id' => 20]);
134 * Test the submit function of the membership form.
136 public function testSubmit() {
137 $form = $this->getForm();
138 $this->createLoggedInUser();
140 'cid' => $this->_individualId
,
141 'join_date' => date('m/d/Y', time()),
144 // This format reflects the 23 being the organisation & the 25 being the type.
145 'membership_type_id' => [23, $this->membershipTypeAnnualFixedID
],
150 'total_amount' => '50.00',
151 //Member dues, see data.xml
152 'financial_type_id' => '2',
153 'soft_credit_type_id' => '',
154 'soft_credit_contact_id' => '',
155 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
156 'receipt_text_signup' => 'Thank you text',
157 'payment_processor_id' => $this->_paymentProcessorID
,
158 'credit_card_number' => '4111111111111111',
160 'credit_card_exp_date' => [
162 // TODO: Future proof
165 'credit_card_type' => 'Visa',
166 'billing_first_name' => 'Test',
167 'billing_middlename' => 'Last',
168 'billing_street_address-5' => '10 Test St',
169 'billing_city-5' => 'Test',
170 'billing_state_province_id-5' => '1003',
171 'billing_postal_code-5' => '90210',
172 'billing_country_id-5' => '1228',
174 $form->_contactID
= $this->_individualId
;
176 $form->testSubmit($params);
177 $form->setRenewalMessage();
178 $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId
]);
179 $this->callAPISuccessGetCount('ContributionRecur', ['contact_id' => $this->_individualId
], 0);
180 $contribution = $this->callAPISuccess('Contribution', 'get', [
181 'contact_id' => $this->_individualId
,
185 $this->callAPISuccessGetCount('LineItem', [
186 'entity_id' => $membership['id'],
187 'entity_table' => 'civicrm_membership',
188 'contribution_id' => $contribution['id'],
190 $this->_checkFinancialRecords([
191 'id' => $contribution['id'],
192 'total_amount' => 50,
193 'financial_account_id' => 2,
194 'payment_instrument_id' => $this->callAPISuccessGetValue('PaymentProcessor', [
195 'id' => $this->_paymentProcessorID
,
196 'return' => 'payment_instrument_id',
199 $this->assertEquals([
201 'text' => 'AnnualFixed membership for Mr. Anthony Anderson II has been renewed.',
202 'title' => 'Complete',
206 ], CRM_Core_Session
::singleton()->getStatus());
210 * Test the submit function of the membership form.
212 * @throws \CRM_Core_Exception
214 public function testSubmitRecur() {
215 $form = $this->getForm();
217 $this->callAPISuccess('MembershipType', 'create', [
218 'id' => $this->membershipTypeAnnualFixedID
,
219 'duration_unit' => 'month',
220 'duration_interval' => 1,
221 'auto_renew' => TRUE,
224 $this->createLoggedInUser();
226 'cid' => $this->_individualId
,
228 'join_date' => date('m/d/Y', time()),
232 // This format reflects the 23 being the organisation & the 25 being the type.
233 'membership_type_id' => [23, $this->membershipTypeAnnualFixedID
],
239 'total_amount' => '77.00',
240 //Member dues, see data.xml
241 'financial_type_id' => '2',
242 'soft_credit_type_id' => 11,
243 'soft_credit_contact_id' => '',
244 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
245 'receipt_text' => 'Thank you text',
246 'payment_processor_id' => $this->_paymentProcessorID
,
247 'credit_card_number' => '4111111111111111',
249 'credit_card_exp_date' => [
251 // TODO: Future proof
254 'credit_card_type' => 'Visa',
255 'billing_first_name' => 'Test',
256 'billing_middlename' => 'Last',
257 'billing_street_address-5' => '10 Test St',
258 'billing_city-5' => 'Test',
259 'billing_state_province_id-5' => '1003',
260 'billing_postal_code-5' => '90210',
261 'billing_country_id-5' => '1228',
264 $form->_mode
= 'test';
265 $form->_contactID
= $this->_individualId
;
267 $form->testSubmit($params);
268 $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId
]);
269 $contributionRecur = $this->callAPISuccessGetSingle('ContributionRecur', ['contact_id' => $this->_individualId
]);
270 $this->assertEquals(1, $contributionRecur['is_email_receipt']);
271 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contributionRecur['modified_date'])));
272 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contributionRecur['modified_date'])));
273 $this->assertNotEmpty($contributionRecur['invoice_id']);
274 $this->assertEquals(CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id',
275 'Pending'), $contributionRecur['contribution_status_id']);
276 $this->assertEquals($this->callAPISuccessGetValue('PaymentProcessor', [
277 'id' => $this->_paymentProcessorID
,
278 'return' => 'payment_instrument_id',
279 ]), $contributionRecur['payment_instrument_id']);
281 $contribution = $this->callAPISuccess('Contribution', 'getsingle', [
282 'contact_id' => $this->_individualId
,
286 $this->assertEquals($this->callAPISuccessGetValue('PaymentProcessor', [
287 'id' => $this->_paymentProcessorID
,
288 'return' => 'payment_instrument_id',
289 ]), $contribution['payment_instrument_id']);
290 $this->assertEquals($contributionRecur['id'], $contribution['contribution_recur_id']);
292 $this->callAPISuccessGetCount('LineItem', [
293 'entity_id' => $membership['id'],
294 'entity_table' => 'civicrm_membership',
295 'contribution_id' => $contribution['id'],
298 $this->callAPISuccessGetSingle('address', [
299 'contact_id' => $this->_individualId
,
300 'street_address' => '10 Test St',
301 'postal_code' => 90210,
306 * Test the submit function of the membership form.
308 public function testSubmitRecurCompleteInstant() {
309 $form = $this->getForm();
310 /** @var \CRM_Core_Payment_Dummy $processor */
311 $processor = Civi\Payment\System
::singleton()->getById($this->_paymentProcessorID
);
312 $processor->setDoDirectPaymentResult([
313 'payment_status_id' => 1,
314 'trxn_id' => 'kettles boil water',
318 $this->callAPISuccess('MembershipType', 'create', [
319 'id' => $this->membershipTypeAnnualFixedID
,
320 'duration_unit' => 'month',
321 'duration_interval' => 1,
322 'auto_renew' => TRUE,
324 $this->createLoggedInUser();
327 $form->_contactID
= $this->_individualId
;
328 $params = $this->getBaseSubmitParams();
329 $form->_mode
= 'test';
331 $form->testSubmit($params);
332 $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId
]);
333 $contributionRecur = $this->callAPISuccessGetSingle('ContributionRecur', ['contact_id' => $this->_individualId
]);
334 $this->assertEquals($contributionRecur['id'], $membership['contribution_recur_id']);
335 $this->assertEquals(0, $contributionRecur['is_email_receipt']);
336 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contributionRecur['modified_date'])));
337 $this->assertNotEmpty($contributionRecur['invoice_id']);
338 // @todo fix this part!
340 $this->assertEquals(CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id',
341 'In Progress'), $contributionRecur['contribution_status_id']);
342 $this->assertNotEmpty($contributionRecur['next_sched_contribution_date']);
344 $paymentInstrumentID = $this->callAPISuccessGetValue('PaymentProcessor', [
345 'id' => $this->_paymentProcessorID
,
346 'return' => 'payment_instrument_id',
348 $this->assertEquals($paymentInstrumentID, $contributionRecur['payment_instrument_id']);
350 $contribution = $this->callAPISuccess('Contribution', 'getsingle', [
351 'contact_id' => $this->_individualId
,
354 $this->assertEquals($paymentInstrumentID, $contribution['payment_instrument_id']);
356 $this->assertEquals('kettles boil water', $contribution['trxn_id']);
357 $this->assertEquals(.29, $contribution['fee_amount']);
358 $this->assertEquals(7800.90, $contribution['total_amount']);
359 $this->assertEquals(7800.61, $contribution['net_amount']);
361 $this->callAPISuccessGetCount('LineItem', [
362 'entity_id' => $membership['id'],
363 'entity_table' => 'civicrm_membership',
364 'contribution_id' => $contribution['id'],
369 * Test the submit function of the membership form.
371 * @param string $thousandSeparator
373 * @dataProvider getThousandSeparators
375 public function testSubmitRecurCompleteInstantWithMail($thousandSeparator) {
376 $this->setCurrencySeparators($thousandSeparator);
377 $form = $this->getForm();
378 $this->mut
= new CiviMailUtils($this, TRUE);
379 /** @var \CRM_Core_Payment_Dummy $processor */
380 $processor = Civi\Payment\System
::singleton()->getById($this->_paymentProcessorID
);
381 $processor->setDoDirectPaymentResult([
382 'payment_status_id' => 1,
383 'trxn_id' => 'kettles boil water',
387 $this->callAPISuccess('MembershipType', 'create', [
388 'id' => $this->membershipTypeAnnualFixedID
,
389 'duration_unit' => 'month',
390 'duration_interval' => 1,
391 'auto_renew' => TRUE,
393 $this->createLoggedInUser();
396 $form->_contactID
= $this->_individualId
;
397 $params = $this->getBaseSubmitParams();
398 $params['send_receipt'] = 1;
399 $form->_mode
= 'test';
401 $form->testSubmit($params);
402 $contributionRecur = $this->callAPISuccessGetSingle('ContributionRecur', ['contact_id' => $this->_individualId
]);
403 $this->assertEquals(1, $contributionRecur['is_email_receipt']);
404 $this->mut
->checkMailLog([
405 '$ ' . $this->formatMoneyInput(7800.90),
408 $this->setCurrencySeparators(',');
412 * Test the submit function of the membership form.
414 * @throws \CRM_Core_Exception
416 public function testSubmitPayLater() {
417 $form = $this->getForm(NULL);
418 $this->createLoggedInUser();
419 $originalMembership = $this->callAPISuccessGetSingle('membership', []);
421 'cid' => $this->_individualId
,
422 'join_date' => date('m/d/Y', time()),
425 // This format reflects the 23 being the organisation & the 25 being the type.
426 'membership_type_id' => [23, $this->membershipTypeAnnualFixedID
],
431 'total_amount' => '50.00',
432 //Member dues, see data.xml
433 'financial_type_id' => '2',
434 'soft_credit_type_id' => '',
435 'soft_credit_contact_id' => '',
436 'payment_instrument_id' => 4,
437 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
438 'receipt_text_signup' => 'Thank you text',
439 'payment_processor_id' => $this->_paymentProcessorID
,
440 'record_contribution' => TRUE,
442 'contribution_status_id' => 2,
444 $form->_contactID
= $this->_individualId
;
446 $form->testSubmit($params);
447 $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId
]);
448 $this->assertEquals(strtotime($membership['end_date']), strtotime($originalMembership['end_date']));
449 $contribution = $this->callAPISuccessGetSingle('Contribution', [
450 'contact_id' => $this->_individualId
,
451 'contribution_status_id' => 2,
452 'return' => ["tax_amount", "trxn_id"],
454 $this->assertEquals($contribution['trxn_id'], 777);
455 $this->assertEquals($contribution['tax_amount'], NULL);
457 $this->callAPISuccessGetCount('LineItem', [
458 'entity_id' => $membership['id'],
459 'entity_table' => 'civicrm_membership',
460 'contribution_id' => $contribution['id'],
465 * Test the submit function of the membership form.
467 * @throws \CRM_Core_Exception
469 public function testSubmitPayLaterWithBilling() {
470 $form = $this->getForm(NULL);
471 $this->createLoggedInUser();
472 $originalMembership = $this->callAPISuccessGetSingle('membership', []);
474 'cid' => $this->_individualId
,
475 'join_date' => date('m/d/Y', time()),
478 // This format reflects the 23 being the organisation & the 25 being the type.
479 'membership_type_id' => [23, $this->membershipTypeAnnualFixedID
],
484 'total_amount' => '50.00',
485 //Member dues, see data.xml
486 'financial_type_id' => '2',
487 'soft_credit_type_id' => '',
488 'soft_credit_contact_id' => '',
489 'payment_instrument_id' => 4,
490 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
491 'receipt_text_signup' => 'Thank you text',
492 'payment_processor_id' => $this->_paymentProcessorID
,
493 'record_contribution' => TRUE,
495 'contribution_status_id' => 2,
496 'billing_first_name' => 'Test',
497 'billing_middlename' => 'Last',
498 'billing_street_address-5' => '10 Test St',
499 'billing_city-5' => 'Test',
500 'billing_state_province_id-5' => '1003',
501 'billing_postal_code-5' => '90210',
502 'billing_country_id-5' => '1228',
504 $form->_contactID
= $this->_individualId
;
506 $form->testSubmit($params);
507 $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId
]);
508 $this->assertEquals(strtotime($membership['end_date']), strtotime($originalMembership['end_date']));
509 $contribution = $this->callAPISuccessGetSingle('Contribution', [
510 'contact_id' => $this->_individualId
,
511 'contribution_status_id' => 2,
513 $this->assertEquals($contribution['trxn_id'], 777);
515 $this->callAPISuccessGetCount('LineItem', [
516 'entity_id' => $membership['id'],
517 'entity_table' => 'civicrm_membership',
518 'contribution_id' => $contribution['id'],
520 $this->callAPISuccessGetSingle('address', [
521 'contact_id' => $this->_individualId
,
522 'street_address' => '10 Test St',
523 'postal_code' => 90210,
528 * Test the submit function of the membership form.
530 public function testSubmitComplete() {
531 $form = $this->getForm(NULL);
532 $this->createLoggedInUser();
533 $originalMembership = $this->callAPISuccessGetSingle('membership', []);
535 'cid' => $this->_individualId
,
536 'join_date' => date('m/d/Y', time()),
539 // This format reflects the 23 being the organisation & the 25 being the type.
540 'membership_type_id' => [23, $this->membershipTypeAnnualFixedID
],
545 'total_amount' => '50.00',
546 //Member dues, see data.xml
547 'financial_type_id' => '2',
548 'soft_credit_type_id' => '',
549 'soft_credit_contact_id' => '',
550 'payment_instrument_id' => 4,
551 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
552 'receipt_text_signup' => 'Thank you text',
553 'payment_processor_id' => $this->_paymentProcessorID
,
554 'record_contribution' => TRUE,
556 'contribution_status_id' => 1,
559 $form->_contactID
= $this->_individualId
;
561 $form->testSubmit($params);
562 $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId
]);
563 $this->assertEquals(strtotime($membership['end_date']), strtotime('+ 2 years',
564 strtotime($originalMembership['end_date'])));
565 $contribution = $this->callAPISuccessGetSingle('Contribution', [
566 'contact_id' => $this->_individualId
,
567 'contribution_status_id' => 1,
570 $this->assertEquals($contribution['trxn_id'], 777);
571 $this->assertEquals(.5, $contribution['fee_amount']);
572 $this->callAPISuccessGetCount('LineItem', [
573 'entity_id' => $membership['id'],
574 'entity_table' => 'civicrm_membership',
575 'contribution_id' => $contribution['id'],
580 * Get a membership form object.
582 * We need to instantiate the form to run preprocess, which means we have to trick it about the request method.
584 * @param string $mode
586 * @return \CRM_Member_Form_MembershipRenewal
588 protected function getForm($mode = 'test') {
589 $form = new CRM_Member_Form_MembershipRenewal();
590 $_SERVER['REQUEST_METHOD'] = 'GET';
591 $form->controller
= new CRM_Core_Controller();
593 $form->_mode
= $mode;
594 $form->_id
= $this->_membershipID
;
600 * Get some re-usable parameters for the submit function.
604 protected function getBaseSubmitParams() {
606 'cid' => $this->_individualId
,
608 'join_date' => date('m/d/Y', time()),
612 // This format reflects the 23 being the organisation & the 25 being the type.
613 'membership_type_id' => [23, $this->membershipTypeAnnualFixedID
],
619 'total_amount' => $this->formatMoneyInput('7800.90'),
620 //Member dues, see data.xml
621 'financial_type_id' => '2',
622 'soft_credit_type_id' => 11,
623 'soft_credit_contact_id' => '',
624 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
625 'receipt_text' => 'Thank you text',
626 'payment_processor_id' => $this->_paymentProcessorID
,
627 'credit_card_number' => '4111111111111111',
629 'credit_card_exp_date' => [
631 // TODO: Future proof
634 'credit_card_type' => 'Visa',
635 'billing_first_name' => 'Test',
636 'billing_middlename' => 'Last',
637 'billing_street_address-5' => '10 Test St',
638 'billing_city-5' => 'Test',
639 'billing_state_province_id-5' => '1003',
640 'billing_postal_code-5' => '90210',
641 'billing_country_id-5' => '1228',