Merge pull request #10707 from eileenmcnaughton/civimail
[civicrm-core.git] / tests / phpunit / CRM / Member / Form / MembershipRenewalTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * File for the MembershipTest class
30 *
31 * (PHP 5)
32 *
33 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
34 */
35
36 /**
37 * Test CRM_Member_Form_Membership functions.
38 *
39 * @package CiviCRM
40 * @group headless
41 */
42 class CRM_Member_Form_MembershipRenewalTest extends CiviUnitTestCase {
43
44 /**
45 * Assume empty database with just civicrm_data.
46 */
47 protected $_individualId;
48 protected $_contribution;
49 protected $_financialTypeId = 1;
50 protected $_apiversion;
51 protected $_entity = 'Membership';
52 protected $_params;
53 protected $_ids = array();
54 protected $_paymentProcessorID;
55
56 /**
57 * Membership type ID for annual fixed membership.
58 *
59 * @var int
60 */
61 protected $membershipTypeAnnualFixedID;
62
63 /**
64 * Parameters to create payment processor.
65 *
66 * @var array
67 */
68 protected $_processorParams = array();
69
70 /**
71 * ID of created membership.
72 *
73 * @var int
74 */
75 protected $_membershipID;
76
77 /**
78 * Payment instrument mapping.
79 *
80 * @var array
81 */
82 protected $paymentInstruments = array();
83
84 /**
85 * Test setup for every test.
86 *
87 * Connect to the database, truncate the tables that will be used
88 * and redirect stdin to a temporary file.
89 */
90 public function setUp() {
91 $this->_apiversion = 3;
92 parent::setUp();
93
94 $this->_individualId = $this->individualCreate();
95 $this->_paymentProcessorID = $this->processorCreate();
96 // Insert test data.
97 $op = new PHPUnit_Extensions_Database_Operation_Insert();
98 $op->execute($this->_dbconn,
99 $this->createFlatXMLDataSet(
100 dirname(__FILE__) . '/dataset/data.xml'
101 )
102 );
103 $membershipTypeAnnualFixed = $this->callAPISuccess('membership_type', 'create', array(
104 'domain_id' => 1,
105 'name' => "AnnualFixed",
106 'member_of_contact_id' => 23,
107 'duration_unit' => "year",
108 'duration_interval' => 1,
109 'period_type' => "fixed",
110 'fixed_period_start_day' => "101",
111 'fixed_period_rollover_day' => "1231",
112 'relationship_type_id' => 20,
113 'financial_type_id' => 2,
114 ));
115 $this->membershipTypeAnnualFixedID = $membershipTypeAnnualFixed['id'];
116 $membership = $this->callAPISuccess('Membership', 'create', array(
117 'contact_id' => $this->_individualId,
118 'membership_type_id' => $this->membershipTypeAnnualFixedID,
119 ));
120 $this->_membershipID = $membership['id'];
121
122 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
123 $this->paymentInstruments = $instruments['values'];
124 }
125
126 /**
127 * Clean up after each test.
128 */
129 public function tearDown() {
130 $this->quickCleanUpFinancialEntities();
131 $this->quickCleanup(
132 array(
133 'civicrm_relationship',
134 'civicrm_membership_type',
135 'civicrm_membership',
136 'civicrm_uf_match',
137 'civicrm_address',
138 )
139 );
140 foreach (array(17, 18, 23, 32) as $contactID) {
141 $this->callAPISuccess('contact', 'delete', array('id' => $contactID, 'skip_undelete' => TRUE));
142 }
143 $this->callAPISuccess('relationship_type', 'delete', array('id' => 20));
144 }
145
146 /**
147 * Test the submit function of the membership form.
148 */
149 public function testSubmit() {
150 $form = $this->getForm();
151 $this->createLoggedInUser();
152 $params = array(
153 'cid' => $this->_individualId,
154 'join_date' => date('m/d/Y', time()),
155 'start_date' => '',
156 'end_date' => '',
157 // This format reflects the 23 being the organisation & the 25 being the type.
158 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID),
159 'auto_renew' => '0',
160 'max_related' => '',
161 'num_terms' => '1',
162 'source' => '',
163 'total_amount' => '50.00',
164 //Member dues, see data.xml
165 'financial_type_id' => '2',
166 'soft_credit_type_id' => '',
167 'soft_credit_contact_id' => '',
168 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
169 'receipt_text_signup' => 'Thank you text',
170 'payment_processor_id' => $this->_paymentProcessorID,
171 'credit_card_number' => '4111111111111111',
172 'cvv2' => '123',
173 'credit_card_exp_date' => array(
174 'M' => '9',
175 'Y' => '2024', // TODO: Future proof
176 ),
177 'credit_card_type' => 'Visa',
178 'billing_first_name' => 'Test',
179 'billing_middlename' => 'Last',
180 'billing_street_address-5' => '10 Test St',
181 'billing_city-5' => 'Test',
182 'billing_state_province_id-5' => '1003',
183 'billing_postal_code-5' => '90210',
184 'billing_country_id-5' => '1228',
185 );
186 $form->_contactID = $this->_individualId;
187
188 $form->testSubmit($params);
189 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId));
190 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId), 0);
191 $contribution = $this->callAPISuccess('Contribution', 'get', array(
192 'contact_id' => $this->_individualId,
193 'is_test' => TRUE,
194 ));
195
196 $this->callAPISuccessGetCount('LineItem', array(
197 'entity_id' => $membership['id'],
198 'entity_table' => 'civicrm_membership',
199 'contribution_id' => $contribution['id'],
200 ), 1);
201 $this->_checkFinancialRecords(array(
202 'id' => $contribution['id'],
203 'total_amount' => 50,
204 'financial_account_id' => 2,
205 'payment_instrument_id' => $this->callAPISuccessGetValue('PaymentProcessor', array(
206 'id' => $this->_paymentProcessorID,
207 'return' => 'payment_instrument_id',
208 )),
209 ), 'online');
210 }
211
212 /**
213 * Test the submit function of the membership form.
214 */
215 public function testSubmitRecur() {
216 $form = $this->getForm();
217
218 $this->callAPISuccess('MembershipType', 'create', array(
219 'id' => $this->membershipTypeAnnualFixedID,
220 'duration_unit' => 'month',
221 'duration_interval' => 1,
222 'auto_renew' => TRUE,
223 ));
224 $form->preProcess();
225 $this->createLoggedInUser();
226 $params = array(
227 'cid' => $this->_individualId,
228 'price_set_id' => 0,
229 'join_date' => date('m/d/Y', time()),
230 'start_date' => '',
231 'end_date' => '',
232 'campaign_id' => '',
233 // This format reflects the 23 being the organisation & the 25 being the type.
234 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID),
235 'auto_renew' => '1',
236 'is_recur' => 1,
237 'max_related' => 0,
238 'num_terms' => '1',
239 'source' => '',
240 'total_amount' => '77.00',
241 //Member dues, see data.xml
242 'financial_type_id' => '2',
243 'soft_credit_type_id' => 11,
244 'soft_credit_contact_id' => '',
245 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
246 'receipt_text' => 'Thank you text',
247 'payment_processor_id' => $this->_paymentProcessorID,
248 'credit_card_number' => '4111111111111111',
249 'cvv2' => '123',
250 'credit_card_exp_date' => array(
251 'M' => '9',
252 'Y' => '2019', // TODO: Future proof
253 ),
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',
262 'send_receipt' => 1,
263 );
264 $form->_mode = 'test';
265 $form->_contactID = $this->_individualId;
266
267 $form->testSubmit($params);
268 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId));
269 $contributionRecur = $this->callAPISuccessGetSingle('ContributionRecur', array('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', array(
277 'id' => $this->_paymentProcessorID,
278 'return' => 'payment_instrument_id',
279 )), $contributionRecur['payment_instrument_id']);
280
281 $contribution = $this->callAPISuccess('Contribution', 'getsingle', array(
282 'contact_id' => $this->_individualId,
283 'is_test' => TRUE,
284 ));
285
286 $this->assertEquals($this->callAPISuccessGetValue('PaymentProcessor', array(
287 'id' => $this->_paymentProcessorID,
288 'return' => 'payment_instrument_id',
289 )), $contribution['payment_instrument_id']);
290 $this->assertEquals($contributionRecur['id'], $contribution['contribution_recur_id']);
291
292 $this->callAPISuccessGetCount('LineItem', array(
293 'entity_id' => $membership['id'],
294 'entity_table' => 'civicrm_membership',
295 'contribution_id' => $contribution['id'],
296 ), 1);
297
298 $this->callAPISuccessGetSingle('address', array(
299 'contact_id' => $this->_individualId,
300 'street_address' => '10 Test St',
301 'postal_code' => 90210,
302 ));
303 }
304
305 /**
306 * Test the submit function of the membership form.
307 */
308 public function testSubmitRecurCompleteInstant() {
309 $form = $this->getForm();
310
311 $processor = Civi\Payment\System::singleton()->getById($this->_paymentProcessorID);
312 $processor->setDoDirectPaymentResult(array(
313 'payment_status_id' => 1,
314 'trxn_id' => 'kettles boil water',
315 'fee_amount' => .29,
316 ));
317
318 $this->callAPISuccess('MembershipType', 'create', array(
319 'id' => $this->membershipTypeAnnualFixedID,
320 'duration_unit' => 'month',
321 'duration_interval' => 1,
322 'auto_renew' => TRUE,
323 ));
324 $this->createLoggedInUser();
325 $form->preProcess();
326
327 $form->_contactID = $this->_individualId;
328 $params = $this->getBaseSubmitParams();
329 $form->_mode = 'test';
330
331 $form->testSubmit($params);
332 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId));
333 $contributionRecur = $this->callAPISuccessGetSingle('ContributionRecur', array('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!
339 /*
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']);
343 */
344 $paymentInstrumentID = $this->callAPISuccessGetValue('PaymentProcessor', array(
345 'id' => $this->_paymentProcessorID,
346 'return' => 'payment_instrument_id',
347 ));
348 $this->assertEquals($paymentInstrumentID, $contributionRecur['payment_instrument_id']);
349
350 $contribution = $this->callAPISuccess('Contribution', 'getsingle', array(
351 'contact_id' => $this->_individualId,
352 'is_test' => TRUE,
353 ));
354 $this->assertEquals($paymentInstrumentID, $contribution['payment_instrument_id']);
355
356 $this->assertEquals('kettles boil water', $contribution['trxn_id']);
357 $this->assertEquals(.29, $contribution['fee_amount']);
358 $this->assertEquals(78, $contribution['total_amount']);
359 $this->assertEquals(77.71, $contribution['net_amount']);
360
361 $this->callAPISuccessGetCount('LineItem', array(
362 'entity_id' => $membership['id'],
363 'entity_table' => 'civicrm_membership',
364 'contribution_id' => $contribution['id'],
365 ), 1);
366
367 }
368
369 /**
370 * Test the submit function of the membership form.
371 */
372 public function testSubmitPayLater() {
373 $form = $this->getForm(NULL);
374 $this->createLoggedInUser();
375 $originalMembership = $this->callAPISuccessGetSingle('membership', array());
376 $params = array(
377 'cid' => $this->_individualId,
378 'join_date' => date('m/d/Y', time()),
379 'start_date' => '',
380 'end_date' => '',
381 // This format reflects the 23 being the organisation & the 25 being the type.
382 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID),
383 'auto_renew' => '0',
384 'max_related' => '',
385 'num_terms' => '2',
386 'source' => '',
387 'total_amount' => '50.00',
388 //Member dues, see data.xml
389 'financial_type_id' => '2',
390 'soft_credit_type_id' => '',
391 'soft_credit_contact_id' => '',
392 'payment_instrument_id' => 4,
393 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
394 'receipt_text_signup' => 'Thank you text',
395 'payment_processor_id' => $this->_paymentProcessorID,
396 'record_contribution' => TRUE,
397 'trxn_id' => 777,
398 'contribution_status_id' => 2,
399 );
400 $form->_contactID = $this->_individualId;
401
402 $form->testSubmit($params);
403 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId));
404 $this->assertEquals(strtotime($membership['end_date']), strtotime($originalMembership['end_date']));
405 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
406 'contact_id' => $this->_individualId,
407 'contribution_status_id' => 2,
408 'return' => array("tax_amount", "trxn_id"),
409 ));
410 $this->assertEquals($contribution['trxn_id'], 777);
411 $this->assertEquals($contribution['tax_amount'], NULL);
412
413 $this->callAPISuccessGetCount('LineItem', array(
414 'entity_id' => $membership['id'],
415 'entity_table' => 'civicrm_membership',
416 'contribution_id' => $contribution['id'],
417 ), 1);
418 }
419
420 /**
421 * Test the submit function of the membership form.
422 */
423 public function testSubmitPayLaterWithBilling() {
424 $form = $this->getForm(NULL);
425 $this->createLoggedInUser();
426 $originalMembership = $this->callAPISuccessGetSingle('membership', array());
427 $params = array(
428 'cid' => $this->_individualId,
429 'join_date' => date('m/d/Y', time()),
430 'start_date' => '',
431 'end_date' => '',
432 // This format reflects the 23 being the organisation & the 25 being the type.
433 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID),
434 'auto_renew' => '0',
435 'max_related' => '',
436 'num_terms' => '2',
437 'source' => '',
438 'total_amount' => '50.00',
439 //Member dues, see data.xml
440 'financial_type_id' => '2',
441 'soft_credit_type_id' => '',
442 'soft_credit_contact_id' => '',
443 'payment_instrument_id' => 4,
444 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
445 'receipt_text_signup' => 'Thank you text',
446 'payment_processor_id' => $this->_paymentProcessorID,
447 'record_contribution' => TRUE,
448 'trxn_id' => 777,
449 'contribution_status_id' => 2,
450 'billing_first_name' => 'Test',
451 'billing_middlename' => 'Last',
452 'billing_street_address-5' => '10 Test St',
453 'billing_city-5' => 'Test',
454 'billing_state_province_id-5' => '1003',
455 'billing_postal_code-5' => '90210',
456 'billing_country_id-5' => '1228',
457 );
458 $form->_contactID = $this->_individualId;
459
460 $form->testSubmit($params);
461 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId));
462 $this->assertEquals(strtotime($membership['end_date']), strtotime($originalMembership['end_date']));
463 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
464 'contact_id' => $this->_individualId,
465 'contribution_status_id' => 2,
466 ));
467 $this->assertEquals($contribution['trxn_id'], 777);
468
469 $this->callAPISuccessGetCount('LineItem', array(
470 'entity_id' => $membership['id'],
471 'entity_table' => 'civicrm_membership',
472 'contribution_id' => $contribution['id'],
473 ), 1);
474 $this->callAPISuccessGetSingle('address', array(
475 'contact_id' => $this->_individualId,
476 'street_address' => '10 Test St',
477 'postal_code' => 90210,
478 ));
479 }
480
481 /**
482 * Test the submit function of the membership form.
483 */
484 public function testSubmitComplete() {
485 $form = $this->getForm(NULL);
486 $this->createLoggedInUser();
487 $originalMembership = $this->callAPISuccessGetSingle('membership', array());
488 $params = array(
489 'cid' => $this->_individualId,
490 'join_date' => date('m/d/Y', time()),
491 'start_date' => '',
492 'end_date' => '',
493 // This format reflects the 23 being the organisation & the 25 being the type.
494 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID),
495 'auto_renew' => '0',
496 'max_related' => '',
497 'num_terms' => '2',
498 'source' => '',
499 'total_amount' => '50.00',
500 //Member dues, see data.xml
501 'financial_type_id' => '2',
502 'soft_credit_type_id' => '',
503 'soft_credit_contact_id' => '',
504 'payment_instrument_id' => 4,
505 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
506 'receipt_text_signup' => 'Thank you text',
507 'payment_processor_id' => $this->_paymentProcessorID,
508 'record_contribution' => TRUE,
509 'trxn_id' => 777,
510 'contribution_status_id' => 1,
511 'fee_amount' => .5,
512 );
513 $form->_contactID = $this->_individualId;
514
515 $form->testSubmit($params);
516 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId));
517 $this->assertEquals(strtotime($membership['end_date']), strtotime('+ 2 years',
518 strtotime($originalMembership['end_date'])));
519 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
520 'contact_id' => $this->_individualId,
521 'contribution_status_id' => 1,
522 ));
523
524 $this->assertEquals($contribution['trxn_id'], 777);
525 $this->assertEquals(.5, $contribution['fee_amount']);
526 $this->callAPISuccessGetCount('LineItem', array(
527 'entity_id' => $membership['id'],
528 'entity_table' => 'civicrm_membership',
529 'contribution_id' => $contribution['id'],
530 ), 1);
531 }
532
533 /**
534 * Get a membership form object.
535 *
536 * We need to instantiate the form to run preprocess, which means we have to trick it about the request method.
537 *
538 * @param string $mode
539 *
540 * @return \CRM_Member_Form_MembershipRenewal
541 */
542 protected function getForm($mode = 'test') {
543 $form = new CRM_Member_Form_MembershipRenewal();
544 $_SERVER['REQUEST_METHOD'] = 'GET';
545 $form->controller = new CRM_Core_Controller();
546 $form->_bltID = 5;
547 $form->_mode = $mode;
548 $form->_id = $this->_membershipID;
549 $form->preProcess();
550 return $form;
551 }
552
553 /**
554 * Get some re-usable parameters for the submit function.
555 *
556 * @return array
557 */
558 protected function getBaseSubmitParams() {
559 $params = array(
560 'cid' => $this->_individualId,
561 'price_set_id' => 0,
562 'join_date' => date('m/d/Y', time()),
563 'start_date' => '',
564 'end_date' => '',
565 'campaign_id' => '',
566 // This format reflects the 23 being the organisation & the 25 being the type.
567 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID),
568 'auto_renew' => '1',
569 'is_recur' => 1,
570 'max_related' => 0,
571 'num_terms' => '1',
572 'source' => '',
573 'total_amount' => '78.00',
574 'financial_type_id' => '2', //Member dues, see data.xml
575 'soft_credit_type_id' => 11,
576 'soft_credit_contact_id' => '',
577 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
578 'receipt_text' => 'Thank you text',
579 'payment_processor_id' => $this->_paymentProcessorID,
580 'credit_card_number' => '4111111111111111',
581 'cvv2' => '123',
582 'credit_card_exp_date' => array(
583 'M' => '9',
584 'Y' => '2019', // TODO: Future proof
585 ),
586 'credit_card_type' => 'Visa',
587 'billing_first_name' => 'Test',
588 'billing_middlename' => 'Last',
589 'billing_street_address-5' => '10 Test St',
590 'billing_city-5' => 'Test',
591 'billing_state_province_id-5' => '1003',
592 'billing_postal_code-5' => '90210',
593 'billing_country_id-5' => '1228',
594 );
595 return $params;
596 }
597
598 }